
(function(){

	var EXTUTIL = Ext.util,
	EACH = Ext.each,
	TRUE = true,
	FALSE = false;

	EXTUTIL.Observable = function(){

		var me = this, e = me.events;
		if(me.listeners){
			me.on(me.listeners);
			delete me.listeners;
		}
		me.events = e || {};
	};

	EXTUTIL.Observable.prototype = {

		filterOptRe : /^(?:scope|delay|buffer|single)$/,


		fireEvent : function(){
			var a = Array.prototype.slice.call(arguments, 0),
			ename = a[0].toLowerCase(),
			me = this,
			ret = TRUE,
			ce = me.events[ename],
			cc,
			q,
			c;
			if (me.eventsSuspended === TRUE) {
				if (q = me.eventQueue) {
					q.push(a);
				}
			}
			else if(typeof ce == 'object') {
				if (ce.bubble){
					if(ce.fire.apply(ce, a.slice(1)) === FALSE) {
						return FALSE;
					}
					c = me.getBubbleTarget && me.getBubbleTarget();
					if(c && c.enableBubble) {
						cc = c.events[ename];
						if(!cc || typeof cc != 'object' || !cc.bubble) {
							c.enableBubble(ename);
						}
						return c.fireEvent.apply(c, a);
					}
				}
				else {
					a.shift();
					ret = ce.fire.apply(ce, a);
				}
			}
			return ret;
		},


		addListener : function(eventName, fn, scope, o){
			var me = this,
			e,
			oe,
			ce;

			if (typeof eventName == 'object') {
				o = eventName;
				for (e in o) {
					oe = o[e];
					if (!me.filterOptRe.test(e)) {
						me.addListener(e, oe.fn || oe, oe.scope || o.scope, oe.fn ? oe : o);
					}
				}
			} else {
				eventName = eventName.toLowerCase();
				ce = me.events[eventName] || TRUE;
				if (typeof ce == 'boolean') {
					me.events[eventName] = ce = new EXTUTIL.Event(me, eventName);
				}
				ce.addListener(fn, scope, typeof o == 'object' ? o : {});
			}
		},


		removeListener : function(eventName, fn, scope){
			var ce = this.events[eventName.toLowerCase()];
			if (typeof ce == 'object') {
				ce.removeListener(fn, scope);
			}
		},


		purgeListeners : function(){
			var events = this.events,
			evt,
			key;
			for(key in events){
				evt = events[key];
				if(typeof evt == 'object'){
					evt.clearListeners();
				}
			}
		},


		addEvents : function(o){
			var me = this;
			me.events = me.events || {};
			if (typeof o == 'string') {
				var a = arguments,
				i = a.length;
				while(i--) {
					me.events[a[i]] = me.events[a[i]] || TRUE;
				}
			} else {
				Ext.applyIf(me.events, o);
			}
		},


		hasListener : function(eventName){
			var e = this.events[eventName.toLowerCase()];
			return typeof e == 'object' && e.listeners.length > 0;
		},


		suspendEvents : function(queueSuspended){
			this.eventsSuspended = TRUE;
			if(queueSuspended && !this.eventQueue){
				this.eventQueue = [];
			}
		},


		resumeEvents : function(){
			var me = this,
			queued = me.eventQueue || [];
			me.eventsSuspended = FALSE;
			delete me.eventQueue;
			EACH(queued, function(e) {
				me.fireEvent.apply(me, e);
			});
		}
	};

	var OBSERVABLE = EXTUTIL.Observable.prototype;

	OBSERVABLE.on = OBSERVABLE.addListener;

	OBSERVABLE.un = OBSERVABLE.removeListener;


	EXTUTIL.Observable.releaseCapture = function(o){
		o.fireEvent = OBSERVABLE.fireEvent;
	};

	function createTargeted(h, o, scope){
		return function(){
			if(o.target == arguments[0]){
				h.apply(scope, Array.prototype.slice.call(arguments, 0));
			}
		};
	};

	function createBuffered(h, o, l, scope){
		l.task = new EXTUTIL.DelayedTask();
		return function(){
			l.task.delay(o.buffer, h, scope, Array.prototype.slice.call(arguments, 0));
		};
	};

	function createSingle(h, e, fn, scope){
		return function(){
			e.removeListener(fn, scope);
			return h.apply(scope, arguments);
		};
	};

	function createDelayed(h, o, l, scope){
		return function(){
			var task = new EXTUTIL.DelayedTask(),
			args = Array.prototype.slice.call(arguments, 0);
			if(!l.tasks) {
				l.tasks = [];
			}
			l.tasks.push(task);
			task.delay(o.delay || 10, function(){
				l.tasks.remove(task);
				h.apply(scope, args);
			}, scope);
		};
	};

	EXTUTIL.Event = function(obj, name){
		this.name = name;
		this.obj = obj;
		this.listeners = [];
	};

	EXTUTIL.Event.prototype = {
		addListener : function(fn, scope, options){
			var me = this,
			l;
			scope = scope || me.obj;
			if(!me.isListening(fn, scope)){
				l = me.createListener(fn, scope, options);
				if(me.firing){
					me.listeners = me.listeners.slice(0);
				}
				me.listeners.push(l);
			}
		},

		createListener: function(fn, scope, o){
			o = o || {};
			scope = scope || this.obj;
			var l = {
				fn: fn,
				scope: scope,
				options: o
			}, h = fn;
			if(o.target){
				h = createTargeted(h, o, scope);
			}
			if(o.delay){
				h = createDelayed(h, o, l, scope);
			}
			if(o.single){
				h = createSingle(h, this, fn, scope);
			}
			if(o.buffer){
				h = createBuffered(h, o, l, scope);
			}
			l.fireFn = h;
			return l;
		},

		findListener : function(fn, scope){
			var list = this.listeners,
			i = list.length,
			l;

			scope = scope || this.obj;
			while(i--){
				l = list[i];
				if(l){
					if(l.fn == fn && l.scope == scope){
						return i;
					}
				}
			}
			return -1;
		},

		isListening : function(fn, scope){
			return this.findListener(fn, scope) != -1;
		},

		removeListener : function(fn, scope){
			var index,
			l,
			k,
			me = this,
			ret = FALSE;
			if((index = me.findListener(fn, scope)) != -1){
				if (me.firing) {
					me.listeners = me.listeners.slice(0);
				}
				l = me.listeners[index];
				if(l.task) {
					l.task.cancel();
					delete l.task;
				}
				k = l.tasks && l.tasks.length;
				if(k) {
					while(k--) {
						l.tasks[k].cancel();
					}
					delete l.tasks;
				}
				me.listeners.splice(index, 1);
				ret = TRUE;
			}
			return ret;
		},


		clearListeners : function(){
			var me = this,
			l = me.listeners,
			i = l.length;
			while(i--) {
				me.removeListener(l[i].fn, l[i].scope);
			}
		},

		fire : function(){
			var me = this,
			listeners = me.listeners,
			len = listeners.length,
			i = 0,
			l;

			if(len > 0){
				me.firing = TRUE;
				var args = Array.prototype.slice.call(arguments, 0);
				for (; i < len; i++) {
					l = listeners[i];
					if(l && l.fireFn.apply(l.scope || me.obj || window, args) === FALSE) {
						return (me.firing = FALSE);
					}
				}
			}
			me.firing = FALSE;
			return TRUE;
		}

	};
})();

Ext.DomHelper = function(){
	var tempTableEl = null,
	emptyTags = /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i,
	tableRe = /^table|tbody|tr|td$/i,
	confRe = /tag|children|cn|html$/i,
	tableElRe = /td|tr|tbody/i,
	cssRe = /([a-z0-9-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi,
	endRe = /end/i,
	pub,

	afterbegin = 'afterbegin',
	afterend = 'afterend',
	beforebegin = 'beforebegin',
	beforeend = 'beforeend',
	ts = '<table>',
	te = '</table>',
	tbs = ts+'<tbody>',
	tbe = '</tbody>'+te,
	trs = tbs + '<tr>',
	tre = '</tr>'+tbe;


	function doInsert(el, o, returnElement, pos, sibling, append){
		var newNode = pub.insertHtml(pos, Ext.getDom(el), createHtml(o));
		return returnElement ? Ext.get(newNode, true) : newNode;
	}


	function createHtml(o){
		var b = '',
		attr,
		val,
		key,
		cn;

		if(typeof o == "string"){
			b = o;
		} else if (Ext.isArray(o)) {
			for (var i=0; i < o.length; i++) {
				if(o[i]) {
					b += createHtml(o[i]);
				}
			};
		} else {
			b += '<' + (o.tag = o.tag || 'div');
			for (attr in o) {
				val = o[attr];
				if(!confRe.test(attr)){
					if (typeof val == "object") {
						b += ' ' + attr + '="';
						for (key in val) {
							b += key + ':' + val[key] + ';';
						};
						b += '"';
					}else{
						b += ' ' + ({
							cls : 'class',
							htmlFor : 'for'
						}
						[attr] || attr) + '="' + val + '"';
					}
				}
			};

			if (emptyTags.test(o.tag)) {
				b += '/>';
			} else {
				b += '>';
				if ((cn = o.children || o.cn)) {
					b += createHtml(cn);
				} else if(o.html){
					b += o.html;
				}
				b += '</' + o.tag + '>';
			}
		}
		return b;
	}

	function ieTable(depth, s, h, e){
		tempTableEl.innerHTML = [s, h, e].join('');
		var i = -1,
		el = tempTableEl,
		ns;
		while(++i < depth){
			el = el.firstChild;
		}

		if(ns = el.nextSibling){
			var df = document.createDocumentFragment();
			while(el){
				ns = el.nextSibling;
				df.appendChild(el);
				el = ns;
			}
			el = df;
		}
		return el;
	}


	function insertIntoTable(tag, where, el, html) {
		var node,
		before;

		tempTableEl = tempTableEl || document.createElement('div');

		if(tag == 'td' && (where == afterbegin || where == beforeend) ||
			!tableElRe.test(tag) && (where == beforebegin || where == afterend)) {
			return;
		}
		before = where == beforebegin ? el :
		where == afterend ? el.nextSibling :
		where == afterbegin ? el.firstChild : null;

		if (where == beforebegin || where == afterend) {
			el = el.parentNode;
		}

		if (tag == 'td' || (tag == 'tr' && (where == beforeend || where == afterbegin))) {
			node = ieTable(4, trs, html, tre);
		} else if ((tag == 'tbody' && (where == beforeend || where == afterbegin)) ||
			(tag == 'tr' && (where == beforebegin || where == afterend))) {
			node = ieTable(3, tbs, html, tbe);
		} else {
			node = ieTable(2, ts, html, te);
		}
		el.insertBefore(node, before);
		return node;
	}


	pub = {

		markup : function(o){
			return createHtml(o);
		},


		applyStyles : function(el, styles){
			if (styles) {
				var matches;

				el = Ext.fly(el);
				if (typeof styles == "function") {
					styles = styles.call();
				}
				if (typeof styles == "string") {

					cssRe.lastIndex = 0;
					while ((matches = cssRe.exec(styles))) {
						el.setStyle(matches[1], matches[2]);
					}
				} else if (typeof styles == "object") {
					el.setStyle(styles);
				}
			}
		},


		insertHtml : function(where, el, html){
			var hash = {},
			hashVal,
			setStart,
			range,
			frag,
			rangeEl,
			rs;

			where = where.toLowerCase();

			hash[beforebegin] = ['BeforeBegin', 'previousSibling'];
			hash[afterend] = ['AfterEnd', 'nextSibling'];

			if (el.insertAdjacentHTML) {
				if(tableRe.test(el.tagName) && (rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html))){
					return rs;
				}

				hash[afterbegin] = ['AfterBegin', 'firstChild'];
				hash[beforeend] = ['BeforeEnd', 'lastChild'];
				if ((hashVal = hash[where])) {
					el.insertAdjacentHTML(hashVal[0], html);
					return el[hashVal[1]];
				}
			} else {
				range = el.ownerDocument.createRange();
				setStart = 'setStart' + (endRe.test(where) ? 'After' : 'Before');
				if (hash[where]) {
					range[setStart](el);
					frag = range.createContextualFragment(html);
					el.parentNode.insertBefore(frag, where == beforebegin ? el : el.nextSibling);
					return el[(where == beforebegin ? 'previous' : 'next') + 'Sibling'];
				} else {
					rangeEl = (where == afterbegin ? 'first' : 'last') + 'Child';
					if (el.firstChild) {
						range[setStart](el[rangeEl]);
						frag = range.createContextualFragment(html);
						if(where == afterbegin){
							el.insertBefore(frag, el.firstChild);
						}else{
							el.appendChild(frag);
						}
					} else {
						el.innerHTML = html;
					}
					return el[rangeEl];
				}
			}
			throw 'Illegal insertion point -> "' + where + '"';
		},


		insertBefore : function(el, o, returnElement){
			return doInsert(el, o, returnElement, beforebegin);
		},


		insertAfter : function(el, o, returnElement){
			return doInsert(el, o, returnElement, afterend, 'nextSibling');
		},


		insertFirst : function(el, o, returnElement){
			return doInsert(el, o, returnElement, afterbegin, 'firstChild');
		},


		append : function(el, o, returnElement){
			return doInsert(el, o, returnElement, beforeend, '', true);
		},


		overwrite : function(el, o, returnElement){
			el = Ext.getDom(el);
			el.innerHTML = createHtml(o);
			return returnElement ? Ext.get(el.firstChild) : el.firstChild;
		},

		createHtml : createHtml
	};
	return pub;
}();

Ext.Template = function(html){
	var me = this,
	a = arguments,
	buf = [],
	v;

	if (Ext.isArray(html)) {
		html = html.join("");
	} else if (a.length > 1) {
		for(var i = 0, len = a.length; i < len; i++){
			v = a[i];
			if(typeof v == 'object'){
				Ext.apply(me, v);
			} else {
				buf.push(v);
			}
		};
		html = buf.join('');
	}


	me.html = html;

	if (me.compiled) {
		me.compile();
	}
};
Ext.Template.prototype = {

	re : /\{([\w-]+)\}/g,



	applyTemplate : function(values){
		var me = this;

		return me.compiled ?
		me.compiled(values) :
		me.html.replace(me.re, function(m, name){
			return values[name] !== undefined ? values[name] : "";
		});
	},


	set : function(html, compile){
		var me = this;
		me.html = html;
		me.compiled = null;
		return compile ? me.compile() : me;
	},


	compile : function(){
		var me = this,
		sep = Ext.isGecko ? "+" : ",";

		function fn(m, name){
			name = "values['" + name + "']";
			return "'"+ sep + '(' + name + " == undefined ? '' : " + name + ')' + sep + "'";
		}

		eval("this.compiled = function(values){ return " + (Ext.isGecko ? "'" : "['") +
			me.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +
			(Ext.isGecko ?  "';};" : "'].join('');};"));
		return me;
	},


	insertFirst: function(el, values, returnElement){
		return this.doInsert('afterBegin', el, values, returnElement);
	},


	insertBefore: function(el, values, returnElement){
		return this.doInsert('beforeBegin', el, values, returnElement);
	},


	insertAfter : function(el, values, returnElement){
		return this.doInsert('afterEnd', el, values, returnElement);
	},


	append : function(el, values, returnElement){
		return this.doInsert('beforeEnd', el, values, returnElement);
	},

	doInsert : function(where, el, values, returnEl){
		el = Ext.getDom(el);
		var newNode = Ext.DomHelper.insertHtml(where, el, this.applyTemplate(values));
		return returnEl ? Ext.get(newNode, true) : newNode;
	},


	overwrite : function(el, values, returnElement){
		el = Ext.getDom(el);
		el.innerHTML = this.applyTemplate(values);
		return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;
	}
};

Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;


Ext.Template.from = function(el, config){
	el = Ext.getDom(el);
	return new Ext.Template(el.value || el.innerHTML, config || '');
};


Ext.DomQuery = function(){
	var cache = {},
	simpleCache = {},
	valueCache = {},
	nonSpace = /\S/,
	trimRe = /^\s+|\s+$/g,
	tplRe = /\{(\d+)\}/g,
	modeRe = /^(\s?[\/>+~]\s?|\s|$)/,
	tagTokenRe = /^(#)?([\w-\*]+)/,
	nthRe = /(\d*)n\+?(\d*)/,
	nthRe2 = /\D/,



	isIE = window.ActiveXObject ? true : false,
	key = 30803;



	eval("var batch = 30803;");



	function child(parent, index){
		var i = 0,
		n = parent.firstChild;
		while(n){
			if(n.nodeType == 1){
				if(++i == index){
					return n;
				}
			}
			n = n.nextSibling;
		}
		return null;
	}


	function next(n){
		while((n = n.nextSibling) && n.nodeType != 1);
		return n;
	}


	function prev(n){
		while((n = n.previousSibling) && n.nodeType != 1);
		return n;
	}



	function children(parent){
		var n = parent.firstChild,
		nodeIndex = -1,
		nextNode;
		while(n){
			nextNode = n.nextSibling;

			if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
				parent.removeChild(n);
			}else{

				n.nodeIndex = ++nodeIndex;
			}
			n = nextNode;
		}
		return this;
	}




	function byClassName(nodeSet, cls){
		if(!cls){
			return nodeSet;
		}
		var result = [], ri = -1;
		for(var i = 0, ci; ci = nodeSet[i]; i++){
			if((' '+ci.className+' ').indexOf(cls) != -1){
				result[++ri] = ci;
			}
		}
		return result;
	};

	function attrValue(n, attr){

		if(!n.tagName && typeof n.length != "undefined"){
			n = n[0];
		}
		if(!n){
			return null;
		}

		if(attr == "for"){
			return n.htmlFor;
		}
		if(attr == "class" || attr == "className"){
			return n.className;
		}
		return n.getAttribute(attr) || n[attr];

	};





	function getNodes(ns, mode, tagName){
		var result = [], ri = -1, cs;
		if(!ns){
			return result;
		}
		tagName = tagName || "*";

		if(typeof ns.getElementsByTagName != "undefined"){
			ns = [ns];
		}



		if(!mode){
			for(var i = 0, ni; ni = ns[i]; i++){
				cs = ni.getElementsByTagName(tagName);
				for(var j = 0, ci; ci = cs[j]; j++){
					result[++ri] = ci;
				}
			}


		} else if(mode == "/" || mode == ">"){
			var utag = tagName.toUpperCase();
			for(var i = 0, ni, cn; ni = ns[i]; i++){
				cn = ni.childNodes;
				for(var j = 0, cj; cj = cn[j]; j++){
					if(cj.nodeName == utag || cj.nodeName == tagName  || tagName == '*'){
						result[++ri] = cj;
					}
				}
			}


		}else if(mode == "+"){
			var utag = tagName.toUpperCase();
			for(var i = 0, n; n = ns[i]; i++){
				while((n = n.nextSibling) && n.nodeType != 1);
				if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){
					result[++ri] = n;
				}
			}


		}else if(mode == "~"){
			var utag = tagName.toUpperCase();
			for(var i = 0, n; n = ns[i]; i++){
				while((n = n.nextSibling)){
					if (n.nodeName == utag || n.nodeName == tagName || tagName == '*'){
						result[++ri] = n;
					}
				}
			}
		}
		return result;
	}

	function concat(a, b){
		if(b.slice){
			return a.concat(b);
		}
		for(var i = 0, l = b.length; i < l; i++){
			a[a.length] = b[i];
		}
		return a;
	}

	function byTag(cs, tagName){
		if(cs.tagName || cs == document){
			cs = [cs];
		}
		if(!tagName){
			return cs;
		}
		var result = [], ri = -1;
		tagName = tagName.toLowerCase();
		for(var i = 0, ci; ci = cs[i]; i++){
			if(ci.nodeType == 1 && ci.tagName.toLowerCase() == tagName){
				result[++ri] = ci;
			}
		}
		return result;
	}

	function byId(cs, id){
		if(cs.tagName || cs == document){
			cs = [cs];
		}
		if(!id){
			return cs;
		}
		var result = [], ri = -1;
		for(var i = 0, ci; ci = cs[i]; i++){
			if(ci && ci.id == id){
				result[++ri] = ci;
				return result;
			}
		}
		return result;
	}



	function byAttribute(cs, attr, value, op, custom){
		var result = [],
		ri = -1,
		useGetStyle = custom == "{",
		fn = Ext.DomQuery.operators[op],
		a,
		xml,
		hasXml;

		for(var i = 0, ci; ci = cs[i]; i++){

			if(ci.nodeType != 1){
				continue;
			}

			if(!hasXml){
				xml = Ext.DomQuery.isXml(ci);
				hasXml = true;
			}


			if(!xml){
				if(useGetStyle){
					a = Ext.DomQuery.getStyle(ci, attr);
				} else if (attr == "class" || attr == "className"){
					a = ci.className;
				} else if (attr == "for"){
					a = ci.htmlFor;
				} else if (attr == "href"){


					a = ci.getAttribute("href", 2);
				} else{
					a = ci.getAttribute(attr);
				}
			}else{
				a = ci.getAttribute(attr);
			}
			if((fn && fn(a, value)) || (!fn && a)){
				result[++ri] = ci;
			}
		}
		return result;
	}

	function byPseudo(cs, name, value){
		return Ext.DomQuery.pseudos[name](cs, value);
	}

	function nodupIEXml(cs){
		var d = ++key,
		r;
		cs[0].setAttribute("_nodup", d);
		r = [cs[0]];
		for(var i = 1, len = cs.length; i < len; i++){
			var c = cs[i];
			if(!c.getAttribute("_nodup") != d){
				c.setAttribute("_nodup", d);
				r[r.length] = c;
			}
		}
		for(var i = 0, len = cs.length; i < len; i++){
			cs[i].removeAttribute("_nodup");
		}
		return r;
	}

	function nodup(cs){
		if(!cs){
			return [];
		}
		var len = cs.length, c, i, r = cs, cj, ri = -1;
		if(!len || typeof cs.nodeType != "undefined" || len == 1){
			return cs;
		}
		if(isIE && typeof cs[0].selectSingleNode != "undefined"){
			return nodupIEXml(cs);
		}
		var d = ++key;
		cs[0]._nodup = d;
		for(i = 1; c = cs[i]; i++){
			if(c._nodup != d){
				c._nodup = d;
			}else{
				r = [];
				for(var j = 0; j < i; j++){
					r[++ri] = cs[j];
				}
				for(j = i+1; cj = cs[j]; j++){
					if(cj._nodup != d){
						cj._nodup = d;
						r[++ri] = cj;
					}
				}
				return r;
			}
		}
		return r;
	}

	function quickDiffIEXml(c1, c2){
		var d = ++key,
		r = [];
		for(var i = 0, len = c1.length; i < len; i++){
			c1[i].setAttribute("_qdiff", d);
		}
		for(var i = 0, len = c2.length; i < len; i++){
			if(c2[i].getAttribute("_qdiff") != d){
				r[r.length] = c2[i];
			}
		}
		for(var i = 0, len = c1.length; i < len; i++){
			c1[i].removeAttribute("_qdiff");
		}
		return r;
	}

	function quickDiff(c1, c2){
		var len1 = c1.length,
		d = ++key,
		r = [];
		if(!len1){
			return c2;
		}
		if(isIE && typeof c1[0].selectSingleNode != "undefined"){
			return quickDiffIEXml(c1, c2);
		}
		for(var i = 0; i < len1; i++){
			c1[i]._qdiff = d;
		}
		for(var i = 0, len = c2.length; i < len; i++){
			if(c2[i]._qdiff != d){
				r[r.length] = c2[i];
			}
		}
		return r;
	}

	function quickId(ns, mode, root, id){
		if(ns == root){
			var d = root.ownerDocument || root;
			return d.getElementById(id);
		}
		ns = getNodes(ns, mode, "*");
		return byId(ns, id);
	}

	return {
		getStyle : function(el, name){
			return Ext.fly(el).getStyle(name);
		},

		compile : function(path, type){
			type = type || "select";


			var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"],
			mode,
			lastPath,
			matchers = Ext.DomQuery.matchers,
			matchersLn = matchers.length,
			modeMatch,

			lmode = path.match(modeRe);

			if(lmode && lmode[1]){
				fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";';
				path = path.replace(lmode[1], "");
			}


			while(path.substr(0, 1)=="/"){
				path = path.substr(1);
			}

			while(path && lastPath != path){
				lastPath = path;
				var tokenMatch = path.match(tagTokenRe);
				if(type == "select"){
					if(tokenMatch){

						if(tokenMatch[1] == "#"){
							fn[fn.length] = 'n = quickId(n, mode, root, "'+tokenMatch[2]+'");';
						}else{
							fn[fn.length] = 'n = getNodes(n, mode, "'+tokenMatch[2]+'");';
						}
						path = path.replace(tokenMatch[0], "");
					}else if(path.substr(0, 1) != '@'){
						fn[fn.length] = 'n = getNodes(n, mode, "*");';
					}

				}else{
					if(tokenMatch){
						if(tokenMatch[1] == "#"){
							fn[fn.length] = 'n = byId(n, "'+tokenMatch[2]+'");';
						}else{
							fn[fn.length] = 'n = byTag(n, "'+tokenMatch[2]+'");';
						}
						path = path.replace(tokenMatch[0], "");
					}
				}
				while(!(modeMatch = path.match(modeRe))){
					var matched = false;
					for(var j = 0; j < matchersLn; j++){
						var t = matchers[j];
						var m = path.match(t.re);
						if(m){
							fn[fn.length] = t.select.replace(tplRe, function(x, i){
								return m[i];
							});
							path = path.replace(m[0], "");
							matched = true;
							break;
						}
					}

					if(!matched){
						throw 'Error parsing selector, parsing failed at "' + path + '"';
					}
				}
				if(modeMatch[1]){
					fn[fn.length] = 'mode="'+modeMatch[1].replace(trimRe, "")+'";';
					path = path.replace(modeMatch[1], "");
				}
			}

			fn[fn.length] = "return nodup(n);\n}";


			eval(fn.join(""));
			return f;
		},


		jsSelect: function(path, root, type){

			root = root || document;

			if(typeof root == "string"){
				root = document.getElementById(root);
			}
			var paths = path.split(","),
			results = [];


			for(var i = 0, len = paths.length; i < len; i++){
				var subPath = paths[i].replace(trimRe, "");

				if(!cache[subPath]){
					cache[subPath] = Ext.DomQuery.compile(subPath);
					if(!cache[subPath]){
						throw subPath + " is not a valid selector";
					}
				}
				var result = cache[subPath](root);
				if(result && result != document){
					results = results.concat(result);
				}
			}



			if(paths.length > 1){
				return nodup(results);
			}
			return results;
		},
		isXml: function(el) {
			var docEl = (el ? el.ownerDocument || el : 0).documentElement;
			return docEl ? docEl.nodeName !== "HTML" : false;
		},
		select : document.querySelectorAll ? function(path, root, type) {
			root = root || document;
			if (!Ext.DomQuery.isXml(root)) {
				try {
					var cs = root.querySelectorAll(path);
					return Ext.toArray(cs);
				}
				catch (ex) {}
			}
			return Ext.DomQuery.jsSelect.call(this, path, root, type);
		} : function(path, root, type) {
			return Ext.DomQuery.jsSelect.call(this, path, root, type);
		},


		selectNode : function(path, root){
			return Ext.DomQuery.select(path, root)[0];
		},


		selectValue : function(path, root, defaultValue){
			path = path.replace(trimRe, "");
			if(!valueCache[path]){
				valueCache[path] = Ext.DomQuery.compile(path, "select");
			}
			var n = valueCache[path](root), v;
			n = n[0] ? n[0] : n;





			if (typeof n.normalize == 'function') n.normalize();

			v = (n && n.firstChild ? n.firstChild.nodeValue : null);
			return ((v === null||v === undefined||v==='') ? defaultValue : v);
		},


		selectNumber : function(path, root, defaultValue){
			var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0);
			return parseFloat(v);
		},


		is : function(el, ss){
			if(typeof el == "string"){
				el = document.getElementById(el);
			}
			var isArray = Ext.isArray(el),
			result = Ext.DomQuery.filter(isArray ? el : [el], ss);
			return isArray ? (result.length == el.length) : (result.length > 0);
		},


		filter : function(els, ss, nonMatches){
			ss = ss.replace(trimRe, "");
			if(!simpleCache[ss]){
				simpleCache[ss] = Ext.DomQuery.compile(ss, "simple");
			}
			var result = simpleCache[ss](els);
			return nonMatches ? quickDiff(result, els) : result;
		},


		matchers : [{
			re: /^\.([\w-]+)/,
			select: 'n = byClassName(n, " {1} ");'
		}, {
			re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
			select: 'n = byPseudo(n, "{1}", "{2}");'
		},{
			re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,
			select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
		}, {
			re: /^#([\w-]+)/,
			select: 'n = byId(n, "{1}");'
		},{
			re: /^@([\w-]+)/,
			select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
		}
		],


		operators : {
			"=" : function(a, v){
				return a == v;
			},
			"!=" : function(a, v){
				return a != v;
			},
			"^=" : function(a, v){
				return a && a.substr(0, v.length) == v;
			},
			"$=" : function(a, v){
				return a && a.substr(a.length-v.length) == v;
			},
			"*=" : function(a, v){
				return a && a.indexOf(v) !== -1;
			},
			"%=" : function(a, v){
				return (a % v) == 0;
			},
			"|=" : function(a, v){
				return a && (a == v || a.substr(0, v.length+1) == v+'-');
			},
			"~=" : function(a, v){
				return a && (' '+a+' ').indexOf(' '+v+' ') != -1;
			}
		},


		pseudos : {
			"first-child" : function(c){
				var r = [], ri = -1, n;
				for(var i = 0, ci; ci = n = c[i]; i++){
					while((n = n.previousSibling) && n.nodeType != 1);
					if(!n){
						r[++ri] = ci;
					}
				}
				return r;
			},

			"last-child" : function(c){
				var r = [], ri = -1, n;
				for(var i = 0, ci; ci = n = c[i]; i++){
					while((n = n.nextSibling) && n.nodeType != 1);
					if(!n){
						r[++ri] = ci;
					}
				}
				return r;
			},

			"nth-child" : function(c, a) {
				var r = [], ri = -1,
				m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a),
				f = (m[1] || 1) - 0, l = m[2] - 0;
				for(var i = 0, n; n = c[i]; i++){
					var pn = n.parentNode;
					if (batch != pn._batch) {
						var j = 0;
						for(var cn = pn.firstChild; cn; cn = cn.nextSibling){
							if(cn.nodeType == 1){
								cn.nodeIndex = ++j;
							}
						}
						pn._batch = batch;
					}
					if (f == 1) {
						if (l == 0 || n.nodeIndex == l){
							r[++ri] = n;
						}
					} else if ((n.nodeIndex + l) % f == 0){
						r[++ri] = n;
					}
				}

				return r;
			},

			"only-child" : function(c){
				var r = [], ri = -1;
				;
				for(var i = 0, ci; ci = c[i]; i++){
					if(!prev(ci) && !next(ci)){
						r[++ri] = ci;
					}
				}
				return r;
			},

			"empty" : function(c){
				var r = [], ri = -1;
				for(var i = 0, ci; ci = c[i]; i++){
					var cns = ci.childNodes, j = 0, cn, empty = true;
					while(cn = cns[j]){
						++j;
						if(cn.nodeType == 1 || cn.nodeType == 3){
							empty = false;
							break;
						}
					}
					if(empty){
						r[++ri] = ci;
					}
				}
				return r;
			},

			"contains" : function(c, v){
				var r = [], ri = -1;
				for(var i = 0, ci; ci = c[i]; i++){
					if((ci.textContent||ci.innerText||'').indexOf(v) != -1){
						r[++ri] = ci;
					}
				}
				return r;
			},

			"nodeValue" : function(c, v){
				var r = [], ri = -1;
				for(var i = 0, ci; ci = c[i]; i++){
					if(ci.firstChild && ci.firstChild.nodeValue == v){
						r[++ri] = ci;
					}
				}
				return r;
			},

			"checked" : function(c){
				var r = [], ri = -1;
				for(var i = 0, ci; ci = c[i]; i++){
					if(ci.checked == true){
						r[++ri] = ci;
					}
				}
				return r;
			},

			"not" : function(c, ss){
				return Ext.DomQuery.filter(c, ss, true);
			},

			"any" : function(c, selectors){
				var ss = selectors.split('|'),
				r = [], ri = -1, s;
				for(var i = 0, ci; ci = c[i]; i++){
					for(var j = 0; s = ss[j]; j++){
						if(Ext.DomQuery.is(ci, s)){
							r[++ri] = ci;
							break;
						}
					}
				}
				return r;
			},

			"odd" : function(c){
				return this["nth-child"](c, "odd");
			},

			"even" : function(c){
				return this["nth-child"](c, "even");
			},

			"nth" : function(c, a){
				return c[a-1] || [];
			},

			"first" : function(c){
				return c[0] || [];
			},

			"last" : function(c){
				return c[c.length-1] || [];
			},

			"has" : function(c, ss){
				var s = Ext.DomQuery.select,
				r = [], ri = -1;
				for(var i = 0, ci; ci = c[i]; i++){
					if(s(ss, ci).length > 0){
						r[++ri] = ci;
					}
				}
				return r;
			},

			"next" : function(c, ss){
				var is = Ext.DomQuery.is,
				r = [], ri = -1;
				for(var i = 0, ci; ci = c[i]; i++){
					var n = next(ci);
					if(n && is(n, ss)){
						r[++ri] = ci;
					}
				}
				return r;
			},

			"prev" : function(c, ss){
				var is = Ext.DomQuery.is,
				r = [], ri = -1;
				for(var i = 0, ci; ci = c[i]; i++){
					var n = prev(ci);
					if(n && is(n, ss)){
						r[++ri] = ci;
					}
				}
				return r;
			}
		}
	};
}();


Ext.query = Ext.DomQuery.select;

Ext.util.DelayedTask = function(fn, scope, args){
	var me = this,
	id,
	call = function(){
		clearInterval(id);
		id = null;
		fn.apply(scope, args || []);
	};


	me.delay = function(delay, newFn, newScope, newArgs){
		me.cancel();
		fn = newFn || fn;
		scope = newScope || scope;
		args = newArgs || args;
		id = setInterval(call, delay);
	};


	me.cancel = function(){
		if(id){
			clearInterval(id);
			id = null;
		}
	};
};
(function(){
	var DOC = document;

	Ext.Element = function(element, forceNew){
		var dom = typeof element == "string" ?
		DOC.getElementById(element) : element,
		id;

		if(!dom) return null;

		id = dom.id;

		if(!forceNew && id && Ext.elCache[id]){
			return Ext.elCache[id].el;
		}


		this.dom = dom;


		this.id = id || Ext.id(dom);
	};

	var DH = Ext.DomHelper,
	El = Ext.Element,
	EC = Ext.elCache;

	El.prototype = {

		set : function(o, useSet){
			var el = this.dom,
			attr,
			val,
			useSet = (useSet !== false) && !!el.setAttribute;

			for (attr in o) {
				if (o.hasOwnProperty(attr)) {
					val = o[attr];
					if (attr == 'style') {
						DH.applyStyles(el, val);
					} else if (attr == 'cls') {
						el.className = val;
					} else if (useSet) {
						el.setAttribute(attr, val);
					} else {
						el[attr] = val;
					}
				}
			}
			return this;
		},


















































		defaultUnit : "px",


		is : function(simpleSelector){
			return Ext.DomQuery.is(this.dom, simpleSelector);
		},


		focus : function(defer,  dom) {
			var me = this,
			dom = dom || me.dom;
			try{
				if(Number(defer)){
					me.focus.defer(defer, null, [null, dom]);
				}else{
					dom.focus();
				}
			}catch(e){}
			return me;
		},


		blur : function() {
			try{
				this.dom.blur();
			}catch(e){}
			return this;
		},


		getValue : function(asNumber){
			var val = this.dom.value;
			return asNumber ? parseInt(val, 10) : val;
		},


		addListener : function(eventName, fn, scope, options){
			Ext.EventManager.on(this.dom,  eventName, fn, scope || this, options);
			return this;
		},


		removeListener : function(eventName, fn, scope){
			Ext.EventManager.removeListener(this.dom,  eventName, fn, scope || this);
			return this;
		},


		removeAllListeners : function(){
			Ext.EventManager.removeAll(this.dom);
			return this;
		},


		purgeAllListeners : function() {
			Ext.EventManager.purgeElement(this, true);
			return this;
		},

		addUnits : function(size){
			if(size === "" || size == "auto" || size === undefined){
				size = size || '';
			} else if(!isNaN(size) || !unitPattern.test(size)){
				size = size + (this.defaultUnit || 'px');
			}
			return size;
		},


		load : function(url, params, cb){
			Ext.Ajax.request(Ext.apply({
				params: params,
				url: url.url || url,
				callback: cb,
				el: this.dom,
				indicatorText: url.indicatorText || ''
			}, Ext.isObject(url) ? url : {}));
			return this;
		},


		isBorderBox : function(){
			return Ext.isBorderBox || Ext.isForcedBorderBox || noBoxAdjust[(this.dom.tagName || "").toLowerCase()];
		},


		remove : function(){
			var me = this,
			dom = me.dom;

			if (dom) {
				delete me.dom;
				Ext.removeNode(dom);
			}
		},


		hover : function(overFn, outFn, scope, options){
			var me = this;
			me.on('mouseenter', overFn, scope || me.dom, options);
			me.on('mouseleave', outFn, scope || me.dom, options);
			return me;
		},


		contains : function(el){
			return !el ? false : Ext.lib.Dom.isAncestor(this.dom, el.dom ? el.dom : el);
		},


		getAttributeNS : function(ns, name){
			return this.getAttribute(name, ns);
		},


		getAttribute : Ext.isIE ? function(name, ns){
			var d = this.dom,
			type = typeof d[ns + ":" + name];

			if(['undefined', 'unknown'].indexOf(type) == -1){
				return d[ns + ":" + name];
			}
			return d[name];
		} : function(name, ns){
			var d = this.dom;
			return d.getAttributeNS(ns, name) || d.getAttribute(ns + ":" + name) || d.getAttribute(name) || d[name];
		},


		update : function(html) {
			if (this.dom) {
				this.dom.innerHTML = html;
			}
			return this;
		}
	};

	var ep = El.prototype;

	El.addMethods = function(o){
		Ext.apply(ep, o);
	};


	ep.on = ep.addListener;


	ep.un = ep.removeListener;


	ep.autoBoxAdjust = true;


	var unitPattern = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,
	docEl;




	El.get = function(el){
		var ex,
		elm,
		id;
		if(!el){
			return null;
		}
		if (typeof el == "string") {
			if (!(elm = DOC.getElementById(el))) {
				return null;
			}
			if (EC[el] && EC[el].el) {
				ex = EC[el].el;
				ex.dom = elm;
			} else {
				ex = El.addToCache(new El(elm));
			}
			return ex;
		} else if (el.tagName) {
			if(!(id = el.id)){
				id = Ext.id(el);
			}
			if (EC[id] && EC[id].el) {
				ex = EC[id].el;
				ex.dom = el;
			} else {
				ex = El.addToCache(new El(el));
			}
			return ex;
		} else if (el instanceof El) {
			if(el != docEl){




				if (Ext.isIE && (el.id == undefined || el.id == '')) {
					el.dom = el.dom;
				} else {
					el.dom = DOC.getElementById(el.id) || el.dom;
				}
			}
			return el;
		} else if(el.isComposite) {
			return el;
		} else if(Ext.isArray(el)) {
			return El.select(el);
		} else if(el == DOC) {

			if(!docEl){
				var f = function(){};
				f.prototype = El.prototype;
				docEl = new f();
				docEl.dom = DOC;
			}
			return docEl;
		}
		return null;
	};

	El.addToCache = function(el, id){
		id = id || el.id;
		EC[id] = {
			el:  el,
			data: {},
			events: {}
		};
		return el;
	};


	El.data = function(el, key, value){
		el = El.get(el);
		if (!el) {
			return null;
		}
		var c = EC[el.id].data;
		if(arguments.length == 2){
			return c[key];
		}else{
			return (c[key] = value);
		}
	};




	function garbageCollect(){
		if(!Ext.enableGarbageCollector){
			clearInterval(El.collectorThreadId);
		} else {
			var eid,
			el,
			d,
			o;

			for(eid in EC){
				o = EC[eid];
				if(o.skipGC){
					continue;
				}
				el = o.el;
				d = el.dom;

















				if(!d || !d.parentNode || (!d.offsetParent && !DOC.getElementById(eid))){
					if(Ext.enableListenerCollection){
						Ext.EventManager.removeAll(d);
					}
					delete EC[eid];
				}
			}

			if (Ext.isIE) {
				var t = {};
				for (eid in EC) {
					t[eid] = EC[eid];
				}
				EC = Ext.elCache = t;
			}
		}
	}
	El.collectorThreadId = setInterval(garbageCollect, 30000);

	var flyFn = function(){};
	flyFn.prototype = El.prototype;


	El.Flyweight = function(dom){
		this.dom = dom;
	};

	El.Flyweight.prototype = new flyFn();
	El.Flyweight.prototype.isFlyweight = true;
	El._flyweights = {};


	El.fly = function(el, named){
		var ret = null;
		named = named || '_global';

		if (el = Ext.getDom(el)) {
			(El._flyweights[named] = El._flyweights[named] || new El.Flyweight()).dom = el;
			ret = El._flyweights[named];
		}
		return ret;
	};


	Ext.get = El.get;


	Ext.fly = El.fly;


	var noBoxAdjust = Ext.isStrict ? {
		select:1
	} : {
		input:1,
		select:1,
		textarea:1
	};
	if(Ext.isIE || Ext.isGecko){
		noBoxAdjust['button'] = 1;
	}

})();

Ext.Element.addMethods(function(){
	var PARENTNODE = 'parentNode',
	NEXTSIBLING = 'nextSibling',
	PREVIOUSSIBLING = 'previousSibling',
	DQ = Ext.DomQuery,
	GET = Ext.get;

	return {

		findParent : function(simpleSelector, maxDepth, returnEl){
			var p = this.dom,
			b = document.body,
			depth = 0,
			stopEl;
			if(Ext.isGecko && Object.prototype.toString.call(p) == '[object XULElement]') {
				return null;
			}
			maxDepth = maxDepth || 50;
			if (isNaN(maxDepth)) {
				stopEl = Ext.getDom(maxDepth);
				maxDepth = Number.MAX_VALUE;
			}
			while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){
				if(DQ.is(p, simpleSelector)){
					return returnEl ? GET(p) : p;
				}
				depth++;
				p = p.parentNode;
			}
			return null;
		},


		findParentNode : function(simpleSelector, maxDepth, returnEl){
			var p = Ext.fly(this.dom.parentNode, '_internal');
			return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null;
		},


		up : function(simpleSelector, maxDepth){
			return this.findParentNode(simpleSelector, maxDepth, true);
		},


		select : function(selector){
			return Ext.Element.select(selector, this.dom);
		},


		query : function(selector){
			return DQ.select(selector, this.dom);
		},


		child : function(selector, returnDom){
			var n = DQ.selectNode(selector, this.dom);
			return returnDom ? n : GET(n);
		},


		down : function(selector, returnDom){
			var n = DQ.selectNode(" > " + selector, this.dom);
			return returnDom ? n : GET(n);
		},


		parent : function(selector, returnDom){
			return this.matchNode(PARENTNODE, PARENTNODE, selector, returnDom);
		},


		next : function(selector, returnDom){
			return this.matchNode(NEXTSIBLING, NEXTSIBLING, selector, returnDom);
		},


		prev : function(selector, returnDom){
			return this.matchNode(PREVIOUSSIBLING, PREVIOUSSIBLING, selector, returnDom);
		},



		first : function(selector, returnDom){
			return this.matchNode(NEXTSIBLING, 'firstChild', selector, returnDom);
		},


		last : function(selector, returnDom){
			return this.matchNode(PREVIOUSSIBLING, 'lastChild', selector, returnDom);
		},

		matchNode : function(dir, start, selector, returnDom){
			var n = this.dom[start];
			while(n){
				if(n.nodeType == 1 && (!selector || DQ.is(n, selector))){
					return !returnDom ? GET(n) : n;
				}
				n = n[dir];
			}
			return null;
		}
	};
}());
Ext.Element.addMethods(
	function() {
		var GETDOM = Ext.getDom,
		GET = Ext.get,
		DH = Ext.DomHelper;

		return {

			appendChild: function(el){
				return GET(el).appendTo(this);
			},


			appendTo: function(el){
				GETDOM(el).appendChild(this.dom);
				return this;
			},


			insertBefore: function(el){
				(el = GETDOM(el)).parentNode.insertBefore(this.dom, el);
				return this;
			},


			insertAfter: function(el){
				(el = GETDOM(el)).parentNode.insertBefore(this.dom, el.nextSibling);
				return this;
			},


			insertFirst: function(el, returnDom){
				el = el || {};
				if(el.nodeType || el.dom || typeof el == 'string'){
					el = GETDOM(el);
					this.dom.insertBefore(el, this.dom.firstChild);
					return !returnDom ? GET(el) : el;
				}else{
					return this.createChild(el, this.dom.firstChild, returnDom);
				}
			},


			replace: function(el){
				el = GET(el);
				this.insertBefore(el);
				el.remove();
				return this;
			},


			replaceWith: function(el){
				var me = this;

				if(el.nodeType || el.dom || typeof el == 'string'){
					el = GETDOM(el);
					me.dom.parentNode.insertBefore(el, me.dom);
				}else{
					el = DH.insertBefore(me.dom, el);
				}

				delete Ext.elCache[me.id];
				Ext.removeNode(me.dom);
				me.id = Ext.id(me.dom = el);
				Ext.Element.addToCache(me.isFlyweight ? new Ext.Element(me.dom) : me);
				return me;
			},


			createChild: function(config, insertBefore, returnDom){
				config = config || {
					tag:'div'
				};
				return insertBefore ?
				DH.insertBefore(insertBefore, config, returnDom !== true) :
				DH[!this.dom.firstChild ? 'overwrite' : 'append'](this.dom, config,  returnDom !== true);
			},


			wrap: function(config, returnDom){
				var newEl = DH.insertBefore(this.dom, config || {
					tag: "div"
				}, !returnDom);
				newEl.dom ? newEl.dom.appendChild(this.dom) : newEl.appendChild(this.dom);
				return newEl;
			},


			insertHtml : function(where, html, returnEl){
				var el = DH.insertHtml(where, this.dom, html);
				return returnEl ? Ext.get(el) : el;
			}
		};
	}());
Ext.Element.addMethods(function(){

	var supports = Ext.supports,
	propCache = {},
	camelRe = /(-[a-z])/gi,
	view = document.defaultView,
	opacityRe = /alpha\(opacity=(.*)\)/i,
	trimRe = /^\s+|\s+$/g,
	EL = Ext.Element,
	spacesRe = /\s+/,
	wordsRe = /\w/g,
	PADDING = "padding",
	MARGIN = "margin",
	BORDER = "border",
	LEFT = "-left",
	RIGHT = "-right",
	TOP = "-top",
	BOTTOM = "-bottom",
	WIDTH = "-width",
	MATH = Math,
	HIDDEN = 'hidden',
	ISCLIPPED = 'isClipped',
	OVERFLOW = 'overflow',
	OVERFLOWX = 'overflow-x',
	OVERFLOWY = 'overflow-y',
	ORIGINALCLIP = 'originalClip',

	borders = {
		l: BORDER + LEFT + WIDTH,
		r: BORDER + RIGHT + WIDTH,
		t: BORDER + TOP + WIDTH,
		b: BORDER + BOTTOM + WIDTH
		},
	paddings = {
		l: PADDING + LEFT,
		r: PADDING + RIGHT,
		t: PADDING + TOP,
		b: PADDING + BOTTOM
		},
	margins = {
		l: MARGIN + LEFT,
		r: MARGIN + RIGHT,
		t: MARGIN + TOP,
		b: MARGIN + BOTTOM
		},
	data = Ext.Element.data;



	function camelFn(m, a) {
		return a.charAt(1).toUpperCase();
	}

	function chkCache(prop) {
		return propCache[prop] || (propCache[prop] = prop == 'float' ? (supports.cssFloat ? 'cssFloat' : 'styleFloat') : prop.replace(camelRe, camelFn));
	}

	return {

		adjustWidth : function(width) {
			var me = this;
			var isNum = (typeof width == "number");
			if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
				width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
			}
			return (isNum && width < 0) ? 0 : width;
		},


		adjustHeight : function(height) {
			var me = this;
			var isNum = (typeof height == "number");
			if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
				height -= (me.getBorderWidth("tb") + me.getPadding("tb"));
			}
			return (isNum && height < 0) ? 0 : height;
		},



		addClass : function(className){
			var me = this,
			i,
			len,
			v,
			cls = [];

			if (!Ext.isArray(className)) {
				if (typeof className == 'string' && !this.hasClass(className)) {
					me.dom.className += " " + className;
				}
			}
			else {
				for (i = 0, len = className.length; i < len; i++) {
					v = className[i];
					if (typeof v == 'string' && (' ' + me.dom.className + ' ').indexOf(' ' + v + ' ') == -1) {
						cls.push(v);
					}
				}
				if (cls.length) {
					me.dom.className += " " + cls.join(" ");
				}
			}
			return me;
		},


		removeClass : function(className){
			var me = this,
			i,
			idx,
			len,
			cls,
			elClasses;
			if (!Ext.isArray(className)){
				className = [className];
			}
			if (me.dom && me.dom.className) {
				elClasses = me.dom.className.replace(trimRe, '').split(spacesRe);
				for (i = 0, len = className.length; i < len; i++) {
					cls = className[i];
					if (typeof cls == 'string') {
						cls = cls.replace(trimRe, '');
						idx = elClasses.indexOf(cls);
						if (idx != -1) {
							elClasses.splice(idx, 1);
						}
					}
				}
				me.dom.className = elClasses.join(" ");
			}
			return me;
		},


		radioClass : function(className){
			var cn = this.dom.parentNode.childNodes,
			v,
			i,
			len;
			className = Ext.isArray(className) ? className : [className];
			for (i = 0, len = cn.length; i < len; i++) {
				v = cn[i];
				if (v && v.nodeType == 1) {
					Ext.fly(v, '_internal').removeClass(className);
				}
			};
			return this.addClass(className);
		},


		toggleClass : function(className){
			return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
		},


		hasClass : function(className){
			return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;
		},


		replaceClass : function(oldClassName, newClassName){
			return this.removeClass(oldClassName).addClass(newClassName);
		},

		isStyle : function(style, val) {
			return this.getStyle(style) == val;
		},


		getStyle : function(){
			return view && view.getComputedStyle ?
			function(prop){
				var el = this.dom,
				v,
				cs,
				out,
				display;

				if(el == document){
					return null;
				}
				prop = chkCache(prop);
				out = (v = el.style[prop]) ? v :
				(cs = view.getComputedStyle(el, "")) ? cs[prop] : null;



				if(prop == 'marginRight' && out != '0px' && !supports.correctRightMargin){
					display = el.style.display;
					el.style.display = 'inline-block';
					out = view.getComputedStyle(el, '').marginRight;
					el.style.display = display;
				}

				if(prop == 'backgroundColor' && out == 'rgba(0, 0, 0, 0)' && !supports.correctTransparentColor){
					out = 'transparent';
				}
				return out;
			} :
			function(prop){
				var el = this.dom,
				m,
				cs;

				if(el == document) return null;
				if (prop == 'opacity') {
					if (el.style.filter.match) {
						if(m = el.style.filter.match(opacityRe)){
							var fv = parseFloat(m[1]);
							if(!isNaN(fv)){
								return fv ? fv / 100 : 0;
							}
						}
					}
					return 1;
				}
				prop = chkCache(prop);
				return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
			};
		}(),


		getColor : function(attr, defaultValue, prefix){
			var v = this.getStyle(attr),
			color = (typeof prefix != 'undefined') ? prefix : '#',
			h;

			if(!v || (/transparent|inherit/.test(v))) {
				return defaultValue;
			}
			if(/^r/.test(v)){
				Ext.each(v.slice(4, v.length -1).split(','), function(s){
					h = parseInt(s, 10);
					color += (h < 16 ? '0' : '') + h.toString(16);
				});
			}else{
				v = v.replace('#', '');
				color += v.length == 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v;
			}
			return(color.length > 5 ? color.toLowerCase() : defaultValue);
		},


		setStyle : function(prop, value){
			var tmp, style;

			if (typeof prop != 'object') {
				tmp = {};
				tmp[prop] = value;
				prop = tmp;
			}
			for (style in prop) {
				value = prop[style];
				style == 'opacity' ?
				this.setOpacity(value) :
				this.dom.style[chkCache(style)] = value;
			}
			return this;
		},


		setOpacity : function(opacity, animate){
			var me = this,
			s = me.dom.style;

			if(!animate || !me.anim){
				if(Ext.isIE){
					var opac = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')' : '',
					val = s.filter.replace(opacityRe, '').replace(trimRe, '');

					s.zoom = 1;
					s.filter = val + (val.length > 0 ? ' ' : '') + opac;
				}else{
					s.opacity = opacity;
				}
			}else{
				me.anim({
					opacity: {
						to: opacity
					}
				}, me.preanim(arguments, 1), null, .35, 'easeIn');
		}
		return me;
	},


	clearOpacity : function(){
		var style = this.dom.style;
		if(Ext.isIE){
			if(!Ext.isEmpty(style.filter)){
				style.filter = style.filter.replace(opacityRe, '').replace(trimRe, '');
			}
		}else{
			style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = '';
		}
		return this;
	},


	getHeight : function(contentHeight){
		var me = this,
		dom = me.dom,
		hidden = Ext.isIE && me.isStyle('display', 'none'),
		h = MATH.max(dom.offsetHeight, hidden ? 0 : dom.clientHeight) || 0;

		h = !contentHeight ? h : h - me.getBorderWidth("tb") - me.getPadding("tb");
		return h < 0 ? 0 : h;
	},


	getWidth : function(contentWidth){
		var me = this,
		dom = me.dom,
		hidden = Ext.isIE && me.isStyle('display', 'none'),
		w = MATH.max(dom.offsetWidth, hidden ? 0 : dom.clientWidth) || 0;
		w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");
		return w < 0 ? 0 : w;
	},


	setWidth : function(width, animate){
		var me = this;
		width = me.adjustWidth(width);
		!animate || !me.anim ?
		me.dom.style.width = me.addUnits(width) :
		me.anim({
			width : {
				to : width
			}
		}, me.preanim(arguments, 1));
	return me;
},


setHeight : function(height, animate){
	var me = this;
	height = me.adjustHeight(height);
	!animate || !me.anim ?
	me.dom.style.height = me.addUnits(height) :
	me.anim({
		height : {
			to : height
		}
	}, me.preanim(arguments, 1));
return me;
},


getBorderWidth : function(side){
	return this.addStyles(side, borders);
},


getPadding : function(side){
	return this.addStyles(side, paddings);
},


clip : function(){
	var me = this,
	dom = me.dom;

	if(!data(dom, ISCLIPPED)){
		data(dom, ISCLIPPED, true);
		data(dom, ORIGINALCLIP, {
			o: me.getStyle(OVERFLOW),
			x: me.getStyle(OVERFLOWX),
			y: me.getStyle(OVERFLOWY)
		});
		me.setStyle(OVERFLOW, HIDDEN);
		me.setStyle(OVERFLOWX, HIDDEN);
		me.setStyle(OVERFLOWY, HIDDEN);
	}
	return me;
},


unclip : function(){
	var me = this,
	dom = me.dom;

	if(data(dom, ISCLIPPED)){
		data(dom, ISCLIPPED, false);
		var o = data(dom, ORIGINALCLIP);
		if(o.o){
			me.setStyle(OVERFLOW, o.o);
		}
		if(o.x){
			me.setStyle(OVERFLOWX, o.x);
		}
		if(o.y){
			me.setStyle(OVERFLOWY, o.y);
		}
	}
	return me;
},


addStyles : function(sides, styles){
	var ttlSize = 0,
	sidesArr = sides.match(wordsRe),
	side,
	size,
	i,
	len = sidesArr.length;
	for (i = 0; i < len; i++) {
		side = sidesArr[i];
		size = side && parseInt(this.getStyle(styles[side]), 10);
		if (size) {
			ttlSize += MATH.abs(size);
		}
	}
	return ttlSize;
},

margins : margins
};
}()
);

(function(){
	var D = Ext.lib.Dom,
	LEFT = "left",
	RIGHT = "right",
	TOP = "top",
	BOTTOM = "bottom",
	POSITION = "position",
	STATIC = "static",
	RELATIVE = "relative",
	AUTO = "auto",
	ZINDEX = "z-index";

	Ext.Element.addMethods({

		getX : function(){
			return D.getX(this.dom);
		},


		getY : function(){
			return D.getY(this.dom);
		},


		getXY : function(){
			return D.getXY(this.dom);
		},


		getOffsetsTo : function(el){
			var o = this.getXY(),
			e = Ext.fly(el, '_internal').getXY();
			return [o[0]-e[0],o[1]-e[1]];
		},


		setX : function(x, animate){
			return this.setXY([x, this.getY()], this.animTest(arguments, animate, 1));
		},


		setY : function(y, animate){
			return this.setXY([this.getX(), y], this.animTest(arguments, animate, 1));
		},


		setLeft : function(left){
			this.setStyle(LEFT, this.addUnits(left));
			return this;
		},


		setTop : function(top){
			this.setStyle(TOP, this.addUnits(top));
			return this;
		},


		setRight : function(right){
			this.setStyle(RIGHT, this.addUnits(right));
			return this;
		},


		setBottom : function(bottom){
			this.setStyle(BOTTOM, this.addUnits(bottom));
			return this;
		},


		setXY : function(pos, animate){
			var me = this;
			if(!animate || !me.anim){
				D.setXY(me.dom, pos);
			}else{
				me.anim({
					points: {
						to: pos
					}
				}, me.preanim(arguments, 1), 'motion');
		}
		return me;
	},


	setLocation : function(x, y, animate){
		return this.setXY([x, y], this.animTest(arguments, animate, 2));
	},


	moveTo : function(x, y, animate){
		return this.setXY([x, y], this.animTest(arguments, animate, 2));
	},


	getLeft : function(local){
		return !local ? this.getX() : parseInt(this.getStyle(LEFT), 10) || 0;
	},


	getRight : function(local){
		var me = this;
		return !local ? me.getX() + me.getWidth() : (me.getLeft(true) + me.getWidth()) || 0;
	},


	getTop : function(local) {
		return !local ? this.getY() : parseInt(this.getStyle(TOP), 10) || 0;
	},


	getBottom : function(local){
		var me = this;
		return !local ? me.getY() + me.getHeight() : (me.getTop(true) + me.getHeight()) || 0;
	},


	position : function(pos, zIndex, x, y){
		var me = this;

		if(!pos && me.isStyle(POSITION, STATIC)){
			me.setStyle(POSITION, RELATIVE);
		} else if(pos) {
			me.setStyle(POSITION, pos);
		}
		if(zIndex){
			me.setStyle(ZINDEX, zIndex);
		}
		if(x || y) me.setXY([x || false, y || false]);
	},


	clearPositioning : function(value){
		value = value || '';
		this.setStyle({
			left : value,
			right : value,
			top : value,
			bottom : value,
			"z-index" : "",
			position : STATIC
		});
		return this;
	},


	getPositioning : function(){
		var l = this.getStyle(LEFT);
		var t = this.getStyle(TOP);
		return {
			"position" : this.getStyle(POSITION),
			"left" : l,
			"right" : l ? "" : this.getStyle(RIGHT),
			"top" : t,
			"bottom" : t ? "" : this.getStyle(BOTTOM),
			"z-index" : this.getStyle(ZINDEX)
		};
	},


	setPositioning : function(pc){
		var me = this,
		style = me.dom.style;

		me.setStyle(pc);

		if(pc.right == AUTO){
			style.right = "";
		}
		if(pc.bottom == AUTO){
			style.bottom = "";
		}

		return me;
	},


	translatePoints : function(x, y){
		y = isNaN(x[1]) ? y : x[1];
		x = isNaN(x[0]) ? x : x[0];
		var me = this,
		relative = me.isStyle(POSITION, RELATIVE),
		o = me.getXY(),
		l = parseInt(me.getStyle(LEFT), 10),
		t = parseInt(me.getStyle(TOP), 10);

		l = !isNaN(l) ? l : (relative ? 0 : me.dom.offsetLeft);
		t = !isNaN(t) ? t : (relative ? 0 : me.dom.offsetTop);

		return {
			left: (x - o[0] + l),
			top: (y - o[1] + t)
			};
	},

	animTest : function(args, animate, i) {
		return !!animate && this.preanim ? this.preanim(args, i) : false;
	}
	});
})();
Ext.Element.addMethods({

	isScrollable : function(){
		var dom = this.dom;
		return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth;
	},


	scrollTo : function(side, value){
		this.dom["scroll" + (/top/i.test(side) ? "Top" : "Left")] = value;
		return this;
	},


	getScroll : function(){
		var d = this.dom,
		doc = document,
		body = doc.body,
		docElement = doc.documentElement,
		l,
		t,
		ret;

		if(d == doc || d == body){
			if(Ext.isIE && Ext.isStrict){
				l = docElement.scrollLeft;
				t = docElement.scrollTop;
			}else{
				l = window.pageXOffset;
				t = window.pageYOffset;
			}
			ret = {
				left: l || (body ? body.scrollLeft : 0),
				top: t || (body ? body.scrollTop : 0)
				};
		}else{
			ret = {
				left: d.scrollLeft,
				top: d.scrollTop
				};
		}
		return ret;
	}
});

Ext.Element.VISIBILITY = 1;

Ext.Element.DISPLAY = 2;


Ext.Element.OFFSETS = 3;


Ext.Element.ASCLASS = 4;


Ext.Element.visibilityCls = 'x-hide-nosize';

Ext.Element.addMethods(function(){
	var El = Ext.Element,
	OPACITY = "opacity",
	VISIBILITY = "visibility",
	DISPLAY = "display",
	HIDDEN = "hidden",
	OFFSETS = "offsets",
	ASCLASS = "asclass",
	NONE = "none",
	NOSIZE = 'nosize',
	ORIGINALDISPLAY = 'originalDisplay',
	VISMODE = 'visibilityMode',
	ISVISIBLE = 'isVisible',
	data = El.data,
	getDisplay = function(dom){
		var d = data(dom, ORIGINALDISPLAY);
		if(d === undefined){
			data(dom, ORIGINALDISPLAY, d = '');
		}
		return d;
	},
	getVisMode = function(dom){
		var m = data(dom, VISMODE);
		if(m === undefined){
			data(dom, VISMODE, m = 1);
		}
		return m;
	};

	return {

		originalDisplay : "",
		visibilityMode : 1,


		setVisibilityMode : function(visMode){
			data(this.dom, VISMODE, visMode);
			return this;
		},


		animate : function(args, duration, onComplete, easing, animType){
			this.anim(args, {
				duration: duration,
				callback: onComplete,
				easing: easing
			}, animType);
			return this;
		},


		anim : function(args, opt, animType, defaultDur, defaultEase, cb){
			animType = animType || 'run';
			opt = opt || {};
			var me = this,
			anim = Ext.lib.Anim[animType](
				me.dom,
				args,
				(opt.duration || defaultDur) || .35,
				(opt.easing || defaultEase) || 'easeOut',
				function(){
					if(cb) cb.call(me);
					if(opt.callback) opt.callback.call(opt.scope || me, me, opt);
				},
				me
				);
			opt.anim = anim;
			return anim;
		},


		preanim : function(a, i){
			return !a[i] ? false : (typeof a[i] == 'object' ? a[i]: {
				duration: a[i+1],
				callback: a[i+2],
				easing: a[i+3]
				});
		},


		isVisible : function() {
			var me = this,
			dom = me.dom,
			visible = data(dom, ISVISIBLE);

			if(typeof visible == 'boolean'){
				return visible;
			}

			visible = !me.isStyle(VISIBILITY, HIDDEN) &&
			!me.isStyle(DISPLAY, NONE) &&
			!((getVisMode(dom) == El.ASCLASS) && me.hasClass(me.visibilityCls || El.visibilityCls));

			data(dom, ISVISIBLE, visible);
			return visible;
		},


		setVisible : function(visible, animate){
			var me = this, isDisplay, isVisibility, isOffsets, isNosize,
			dom = me.dom,
			visMode = getVisMode(dom);



			if (typeof animate == 'string'){
				switch (animate) {
					case DISPLAY:
						visMode = El.DISPLAY;
						break;
					case VISIBILITY:
						visMode = El.VISIBILITY;
						break;
					case OFFSETS:
						visMode = El.OFFSETS;
						break;
					case NOSIZE:
					case ASCLASS:
						visMode = El.ASCLASS;
						break;
				}
				me.setVisibilityMode(visMode);
				animate = false;
			}

			if (!animate || !me.anim) {
				if(visMode == El.ASCLASS ){

					me[visible?'removeClass':'addClass'](me.visibilityCls || El.visibilityCls);

				} else if (visMode == El.DISPLAY){

					return me.setDisplayed(visible);

				} else if (visMode == El.OFFSETS){

					if (!visible){
						me.hideModeStyles = {
							position: me.getStyle('position'),
							top: me.getStyle('top'),
							left: me.getStyle('left')
						};
						me.applyStyles({
							position: 'absolute',
							top: '-10000px',
							left: '-10000px'
						});
					} else {
						me.applyStyles(me.hideModeStyles || {
							position: '',
							top: '',
							left: ''
						});
						delete me.hideModeStyles;
					}

				}else{
					me.fixDisplay();
					dom.style.visibility = visible ? "visible" : HIDDEN;
				}
			}else{

				if(visible){
					me.setOpacity(.01);
					me.setVisible(true);
				}
				me.anim({
					opacity: {
						to: (visible?1:0)
					}
				},
				me.preanim(arguments, 1),
				null,
				.35,
				'easeIn',
				function(){
					visible || me.setVisible(false).setOpacity(1);
				});
		}
		data(dom, ISVISIBLE, visible);
		return me;
	},



	hasMetrics  : function(){
		var dom = this.dom;
		return this.isVisible() || (getVisMode(dom) == El.VISIBILITY);
	},


	toggle : function(animate){
		var me = this;
		me.setVisible(!me.isVisible(), me.preanim(arguments, 0));
		return me;
	},


	setDisplayed : function(value) {
		if(typeof value == "boolean"){
			value = value ? getDisplay(this.dom) : NONE;
		}
		this.setStyle(DISPLAY, value);
		return this;
	},


	fixDisplay : function(){
		var me = this;
		if(me.isStyle(DISPLAY, NONE)){
			me.setStyle(VISIBILITY, HIDDEN);
			me.setStyle(DISPLAY, getDisplay(this.dom));
			if(me.isStyle(DISPLAY, NONE)){
				me.setStyle(DISPLAY, "block");
			}
		}
	},


	hide : function(animate){

		if (typeof animate == 'string'){
			this.setVisible(false, animate);
			return this;
		}
		this.setVisible(false, this.preanim(arguments, 0));
		return this;
	},


	show : function(animate){

		if (typeof animate == 'string'){
			this.setVisible(true, animate);
			return this;
		}
		this.setVisible(true, this.preanim(arguments, 0));
		return this;
	}
};
}());
(function(){

	var NULL = null,
	UNDEFINED = undefined,
	TRUE = true,
	FALSE = false,
	SETX = "setX",
	SETY = "setY",
	SETXY = "setXY",
	LEFT = "left",
	BOTTOM = "bottom",
	TOP = "top",
	RIGHT = "right",
	HEIGHT = "height",
	WIDTH = "width",
	POINTS = "points",
	HIDDEN = "hidden",
	ABSOLUTE = "absolute",
	VISIBLE = "visible",
	MOTION = "motion",
	POSITION = "position",
	EASEOUT = "easeOut",

	flyEl = new Ext.Element.Flyweight(),
	queues = {},
	getObject = function(o){
		return o || {};
	},
	fly = function(dom){
		flyEl.dom = dom;
		flyEl.id = Ext.id(dom);
		return flyEl;
	},

	getQueue = function(id){
		if(!queues[id]){
			queues[id] = [];
		}
		return queues[id];
	},
	setQueue = function(id, value){
		queues[id] = value;
	};


	Ext.enableFx = TRUE;


	Ext.Fx = {



		switchStatements : function(key, fn, argHash){
			return fn.apply(this, argHash[key]);
		},


		slideIn : function(anchor, o){
			o = getObject(o);
			var me = this,
			dom = me.dom,
			st = dom.style,
			xy,
			r,
			b,
			wrap,
			after,
			st,
			args,
			pt,
			bw,
			bh;

			anchor = anchor || "t";

			me.queueFx(o, function(){
				xy = fly(dom).getXY();

				fly(dom).fixDisplay();


				r = fly(dom).getFxRestore();
				b = {
					x: xy[0],
					y: xy[1],
					0: xy[0],
					1: xy[1],
					width: dom.offsetWidth,
					height: dom.offsetHeight
					};
				b.right = b.x + b.width;
				b.bottom = b.y + b.height;


				fly(dom).setWidth(b.width).setHeight(b.height);


				wrap = fly(dom).fxWrap(r.pos, o, HIDDEN);

				st.visibility = VISIBLE;
				st.position = ABSOLUTE;


				function after(){
					fly(dom).fxUnwrap(wrap, r.pos, o);
					st.width = r.width;
					st.height = r.height;
					fly(dom).afterFx(o);
				}


				pt = {
					to: [b.x, b.y]
					};
				bw = {
					to: b.width
					};
				bh = {
					to: b.height
					};

				function argCalc(wrap, style, ww, wh, sXY, sXYval, s1, s2, w, h, p){
					var ret = {};
					fly(wrap).setWidth(ww).setHeight(wh);
					if(fly(wrap)[sXY]){
						fly(wrap)[sXY](sXYval);
					}
					style[s1] = style[s2] = "0";
					if(w){
						ret.width = w;
					}
					if(h){
						ret.height = h;
					}
					if(p){
						ret.points = p;
					}
					return ret;
				};

				args = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, {
					t  : [wrap, st, b.width, 0, NULL, NULL, LEFT, BOTTOM, NULL, bh, NULL],
					l  : [wrap, st, 0, b.height, NULL, NULL, RIGHT, TOP, bw, NULL, NULL],
					r  : [wrap, st, b.width, b.height, SETX, b.right, LEFT, TOP, NULL, NULL, pt],
					b  : [wrap, st, b.width, b.height, SETY, b.bottom, LEFT, TOP, NULL, bh, pt],
					tl : [wrap, st, 0, 0, NULL, NULL, RIGHT, BOTTOM, bw, bh, pt],
					bl : [wrap, st, 0, 0, SETY, b.y + b.height, RIGHT, TOP, bw, bh, pt],
					br : [wrap, st, 0, 0, SETXY, [b.right, b.bottom], LEFT, TOP, bw, bh, pt],
					tr : [wrap, st, 0, 0, SETX, b.x + b.width, LEFT, BOTTOM, bw, bh, pt]
				});

				st.visibility = VISIBLE;
				fly(wrap).show();

				arguments.callee.anim = fly(wrap).fxanim(args,
					o,
					MOTION,
					.5,
					EASEOUT,
					after);
			});
			return me;
		},


		slideOut : function(anchor, o){
			o = getObject(o);
			var me = this,
			dom = me.dom,
			st = dom.style,
			xy = me.getXY(),
			wrap,
			r,
			b,
			a,
			zero = {
				to: 0
			};

			anchor = anchor || "t";

			me.queueFx(o, function(){


				r = fly(dom).getFxRestore();
				b = {
					x: xy[0],
					y: xy[1],
					0: xy[0],
					1: xy[1],
					width: dom.offsetWidth,
					height: dom.offsetHeight
					};
				b.right = b.x + b.width;
				b.bottom = b.y + b.height;


				fly(dom).setWidth(b.width).setHeight(b.height);


				wrap = fly(dom).fxWrap(r.pos, o, VISIBLE);

				st.visibility = VISIBLE;
				st.position = ABSOLUTE;
				fly(wrap).setWidth(b.width).setHeight(b.height);

				function after(){
					o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
					fly(dom).fxUnwrap(wrap, r.pos, o);
					st.width = r.width;
					st.height = r.height;
					fly(dom).afterFx(o);
				}

				function argCalc(style, s1, s2, p1, v1, p2, v2, p3, v3){
					var ret = {};

					style[s1] = style[s2] = "0";
					ret[p1] = v1;
					if(p2){
						ret[p2] = v2;
					}
					if(p3){
						ret[p3] = v3;
					}

					return ret;
				};

				a = fly(dom).switchStatements(anchor.toLowerCase(), argCalc, {
					t  : [st, LEFT, BOTTOM, HEIGHT, zero],
					l  : [st, RIGHT, TOP, WIDTH, zero],
					r  : [st, LEFT, TOP, WIDTH, zero, POINTS, {
						to : [b.right, b.y]
						}],
					b  : [st, LEFT, TOP, HEIGHT, zero, POINTS, {
						to : [b.x, b.bottom]
						}],
					tl : [st, RIGHT, BOTTOM, WIDTH, zero, HEIGHT, zero],
					bl : [st, RIGHT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {
						to : [b.x, b.bottom]
						}],
					br : [st, LEFT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {
						to : [b.x + b.width, b.bottom]
						}],
					tr : [st, LEFT, BOTTOM, WIDTH, zero, HEIGHT, zero, POINTS, {
						to : [b.right, b.y]
						}]
				});

				arguments.callee.anim = fly(wrap).fxanim(a,
					o,
					MOTION,
					.5,
					EASEOUT,
					after);
			});
			return me;
		},


		puff : function(o){
			o = getObject(o);
			var me = this,
			dom = me.dom,
			st = dom.style,
			width,
			height,
			r;

			me.queueFx(o, function(){
				width = fly(dom).getWidth();
				height = fly(dom).getHeight();
				fly(dom).clearOpacity();
				fly(dom).show();


				r = fly(dom).getFxRestore();

				function after(){
					o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
					fly(dom).clearOpacity();
					fly(dom).setPositioning(r.pos);
					st.width = r.width;
					st.height = r.height;
					st.fontSize = '';
					fly(dom).afterFx(o);
				}

				arguments.callee.anim = fly(dom).fxanim({
					width : {
						to : fly(dom).adjustWidth(width * 2)
						},
					height : {
						to : fly(dom).adjustHeight(height * 2)
						},
					points : {
						by : [-width * .5, -height * .5]
						},
					opacity : {
						to : 0
					},
					fontSize: {
						to : 200,
						unit: "%"
					}
				},
				o,
				MOTION,
				.5,
				EASEOUT,
				after);
			});
			return me;
		},


		switchOff : function(o){
			o = getObject(o);
			var me = this,
			dom = me.dom,
			st = dom.style,
			r;

			me.queueFx(o, function(){
				fly(dom).clearOpacity();
				fly(dom).clip();


				r = fly(dom).getFxRestore();

				function after(){
					o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
					fly(dom).clearOpacity();
					fly(dom).setPositioning(r.pos);
					st.width = r.width;
					st.height = r.height;
					fly(dom).afterFx(o);
				};

				fly(dom).fxanim({
					opacity : {
						to : 0.3
					}
				},
				NULL,
				NULL,
				.1,
				NULL,
				function(){
					fly(dom).clearOpacity();
					(function(){
						fly(dom).fxanim({
							height : {
								to : 1
							},
							points : {
								by : [0, fly(dom).getHeight() * .5]
								}
						},
						o,
						MOTION,
						0.3,
						'easeIn',
						after);
					}).defer(100);
				});
			});
		return me;
	},


	highlight : function(color, o){
		o = getObject(o);
		var me = this,
		dom = me.dom,
		attr = o.attr || "backgroundColor",
		a = {},
		restore;

		me.queueFx(o, function(){
			fly(dom).clearOpacity();
			fly(dom).show();

			function after(){
				dom.style[attr] = restore;
				fly(dom).afterFx(o);
			}
			restore = dom.style[attr];
			a[attr] = {
				from: color || "ffff9c",
				to: o.endColor || fly(dom).getColor(attr) || "ffffff"
				};
			arguments.callee.anim = fly(dom).fxanim(a,
				o,
				'color',
				1,
				'easeIn',
				after);
		});
		return me;
	},


	frame : function(color, count, o){
		o = getObject(o);
		var me = this,
		dom = me.dom,
		proxy,
		active;

		me.queueFx(o, function(){
			color = color || '#C3DAF9';
			if(color.length == 6){
				color = '#' + color;
			}
			count = count || 1;
			fly(dom).show();

			var xy = fly(dom).getXY(),
			b = {
				x: xy[0],
				y: xy[1],
				0: xy[0],
				1: xy[1],
				width: dom.offsetWidth,
				height: dom.offsetHeight
				},
			queue = function(){
				proxy = fly(document.body || document.documentElement).createChild({
					style:{
						position : ABSOLUTE,
						'z-index': 35000,
						border : '0px solid ' + color
					}
				});
				return proxy.queueFx({}, animFn);
			};


			arguments.callee.anim = {
				isAnimated: true,
				stop: function() {
					count = 0;
					proxy.stopFx();
				}
			};

			function animFn(){
				var scale = Ext.isBorderBox ? 2 : 1;
				active = proxy.anim({
					top : {
						from : b.y,
						to : b.y - 20
						},
					left : {
						from : b.x,
						to : b.x - 20
						},
					borderWidth : {
						from : 0,
						to : 10
					},
					opacity : {
						from : 1,
						to : 0
					},
					height : {
						from : b.height,
						to : b.height + 20 * scale
						},
					width : {
						from : b.width,
						to : b.width + 20 * scale
						}
				},{
					duration: o.duration || 1,
					callback: function() {
						proxy.remove();
						--count > 0 ? queue() : fly(dom).afterFx(o);
					}
				});
				arguments.callee.anim = {
					isAnimated: true,
					stop: function(){
						active.stop();
					}
				};
			};
			queue();
		});
		return me;
	},


	pause : function(seconds){
		var dom = this.dom,
		t;

		this.queueFx({}, function(){
			t = setTimeout(function(){
				fly(dom).afterFx({});
			}, seconds * 1000);
			arguments.callee.anim = {
				isAnimated: true,
				stop: function(){
					clearTimeout(t);
					fly(dom).afterFx({});
				}
			};
		});
		return this;
	},


	fadeIn : function(o){
		o = getObject(o);
		var me = this,
		dom = me.dom,
		to = o.endOpacity || 1;

		me.queueFx(o, function(){
			fly(dom).setOpacity(0);
			fly(dom).fixDisplay();
			dom.style.visibility = VISIBLE;
			arguments.callee.anim = fly(dom).fxanim({
				opacity:{
					to:to
				}
			},
			o, NULL, .5, EASEOUT, function(){
				if(to == 1){
					fly(dom).clearOpacity();
				}
				fly(dom).afterFx(o);
			});
		});
	return me;
},


fadeOut : function(o){
	o = getObject(o);
	var me = this,
	dom = me.dom,
	style = dom.style,
	to = o.endOpacity || 0;

	me.queueFx(o, function(){
		arguments.callee.anim = fly(dom).fxanim({
			opacity : {
				to : to
			}
		},
		o,
		NULL,
		.5,
		EASEOUT,
		function(){
			if(to == 0){
				Ext.Element.data(dom, 'visibilityMode') == Ext.Element.DISPLAY || o.useDisplay ?
				style.display = "none" :
				style.visibility = HIDDEN;

				fly(dom).clearOpacity();
			}
			fly(dom).afterFx(o);
		});
	});
return me;
},


scale : function(w, h, o){
	this.shift(Ext.apply({}, o, {
		width: w,
		height: h
	}));
	return this;
},


shift : function(o){
	o = getObject(o);
	var dom = this.dom,
	a = {};

	this.queueFx(o, function(){
		for (var prop in o) {
			if (o[prop] != UNDEFINED) {
				a[prop] = {
					to : o[prop]
					};
			}
		}

		a.width ? a.width.to = fly(dom).adjustWidth(o.width) : a;
		a.height ? a.height.to = fly(dom).adjustWidth(o.height) : a;

		if (a.x || a.y || a.xy) {
			a.points = a.xy ||
			{
				to : [ a.x ? a.x.to : fly(dom).getX(),
				a.y ? a.y.to : fly(dom).getY()]
				};
		}

		arguments.callee.anim = fly(dom).fxanim(a,
			o,
			MOTION,
			.35,
			EASEOUT,
			function(){
				fly(dom).afterFx(o);
			});
	});
	return this;
},


ghost : function(anchor, o){
	o = getObject(o);
	var me = this,
	dom = me.dom,
	st = dom.style,
	a = {
		opacity: {
			to: 0
		},
		points: {}
},
pt = a.points,
r,
w,
h;

anchor = anchor || "b";

me.queueFx(o, function(){

	r = fly(dom).getFxRestore();
	w = fly(dom).getWidth();
	h = fly(dom).getHeight();

	function after(){
		o.useDisplay ? fly(dom).setDisplayed(FALSE) : fly(dom).hide();
		fly(dom).clearOpacity();
		fly(dom).setPositioning(r.pos);
		st.width = r.width;
		st.height = r.height;
		fly(dom).afterFx(o);
	}

	pt.by = fly(dom).switchStatements(anchor.toLowerCase(), function(v1,v2){
		return [v1, v2];
	}, {
		t  : [0, -h],
		l  : [-w, 0],
		r  : [w, 0],
		b  : [0, h],
		tl : [-w, -h],
		bl : [-w, h],
		br : [w, h],
		tr : [w, -h]
	});

	arguments.callee.anim = fly(dom).fxanim(a,
		o,
		MOTION,
		.5,
		EASEOUT, after);
});
return me;
},


syncFx : function(){
	var me = this;
	me.fxDefaults = Ext.apply(me.fxDefaults || {}, {
		block : FALSE,
		concurrent : TRUE,
		stopFx : FALSE
	});
	return me;
},


sequenceFx : function(){
	var me = this;
	me.fxDefaults = Ext.apply(me.fxDefaults || {}, {
		block : FALSE,
		concurrent : FALSE,
		stopFx : FALSE
	});
	return me;
},


nextFx : function(){
	var ef = getQueue(this.dom.id)[0];
	if(ef){
		ef.call(this);
	}
},


hasActiveFx : function(){
	return getQueue(this.dom.id)[0];
},


stopFx : function(finish){
	var me = this,
	id = me.dom.id;
	if(me.hasActiveFx()){
		var cur = getQueue(id)[0];
		if(cur && cur.anim){
			if(cur.anim.isAnimated){
				setQueue(id, [cur]);
				cur.anim.stop(finish !== undefined ? finish : TRUE);
			}else{
				setQueue(id, []);
			}
		}
	}
	return me;
},


beforeFx : function(o){
	if(this.hasActiveFx() && !o.concurrent){
		if(o.stopFx){
			this.stopFx();
			return TRUE;
		}
		return FALSE;
	}
	return TRUE;
},


hasFxBlock : function(){
	var q = getQueue(this.dom.id);
	return q && q[0] && q[0].block;
},


queueFx : function(o, fn){
	var me = fly(this.dom);
	if(!me.hasFxBlock()){
		Ext.applyIf(o, me.fxDefaults);
		if(!o.concurrent){
			var run = me.beforeFx(o);
			fn.block = o.block;
			getQueue(me.dom.id).push(fn);
			if(run){
				me.nextFx();
			}
		}else{
			fn.call(me);
		}
	}
	return me;
},


fxWrap : function(pos, o, vis){
	var dom = this.dom,
	wrap,
	wrapXY;
	if(!o.wrap || !(wrap = Ext.getDom(o.wrap))){
		if(o.fixPosition){
			wrapXY = fly(dom).getXY();
		}
		var div = document.createElement("div");
		div.style.visibility = vis;
		wrap = dom.parentNode.insertBefore(div, dom);
		fly(wrap).setPositioning(pos);
		if(fly(wrap).isStyle(POSITION, "static")){
			fly(wrap).position("relative");
		}
		fly(dom).clearPositioning('auto');
		fly(wrap).clip();
		wrap.appendChild(dom);
		if(wrapXY){
			fly(wrap).setXY(wrapXY);
		}
	}
	return wrap;
},


fxUnwrap : function(wrap, pos, o){
	var dom = this.dom;
	fly(dom).clearPositioning();
	fly(dom).setPositioning(pos);
	if(!o.wrap){
		var pn = fly(wrap).dom.parentNode;
		pn.insertBefore(dom, wrap);
		fly(wrap).remove();
	}
},


getFxRestore : function(){
	var st = this.dom.style;
	return {
		pos: this.getPositioning(),
		width: st.width,
		height : st.height
		};
},


afterFx : function(o){
	var dom = this.dom,
	id = dom.id;
	if(o.afterStyle){
		fly(dom).setStyle(o.afterStyle);
	}
	if(o.afterCls){
		fly(dom).addClass(o.afterCls);
	}
	if(o.remove == TRUE){
		fly(dom).remove();
	}
	if(o.callback){
		o.callback.call(o.scope, fly(dom));
	}
	if(!o.concurrent){
		getQueue(id).shift();
		fly(dom).nextFx();
	}
},


fxanim : function(args, opt, animType, defaultDur, defaultEase, cb){
	animType = animType || 'run';
	opt = opt || {};
	var anim = Ext.lib.Anim[animType](
		this.dom,
		args,
		(opt.duration || defaultDur) || .35,
		(opt.easing || defaultEase) || EASEOUT,
		cb,
		this
		);
	opt.anim = anim;
	return anim;
}
};


Ext.Fx.resize = Ext.Fx.scale;



Ext.Element.addMethods(Ext.Fx);
})();

Ext.CompositeElementLite = function(els, root){

	this.elements = [];
	this.add(els, root);
	this.el = new Ext.Element.Flyweight();
};

Ext.CompositeElementLite.prototype = {
	isComposite: true,


	getElement : function(el){

		var e = this.el;
		e.dom = el;
		e.id = el.id;
		return e;
	},


	transformElement : function(el){
		return Ext.getDom(el);
	},


	getCount : function(){
		return this.elements.length;
	},

	add : function(els, root){
		var me = this,
		elements = me.elements;
		if(!els){
			return this;
		}
		if(typeof els == "string"){
			els = Ext.Element.selectorFunction(els, root);
		}else if(els.isComposite){
			els = els.elements;
		}else if(!Ext.isIterable(els)){
			els = [els];
		}

		for(var i = 0, len = els.length; i < len; ++i){
			elements.push(me.transformElement(els[i]));
		}
		return me;
	},

	invoke : function(fn, args){
		var me = this,
		els = me.elements,
		len = els.length,
		e,
		i;

		for(i = 0; i < len; i++) {
			e = els[i];
			if(e){
				Ext.Element.prototype[fn].apply(me.getElement(e), args);
			}
		}
		return me;
	},

	item : function(index){
		var me = this,
		el = me.elements[index],
		out = null;

		if(el){
			out = me.getElement(el);
		}
		return out;
	},


	addListener : function(eventName, handler, scope, opt){
		var els = this.elements,
		len = els.length,
		i, e;

		for(i = 0; i<len; i++) {
			e = els[i];
			if(e) {
				Ext.EventManager.on(e, eventName, handler, scope || e, opt);
			}
		}
		return this;
	},

	each : function(fn, scope){
		var me = this,
		els = me.elements,
		len = els.length,
		i, e;

		for(i = 0; i<len; i++) {
			e = els[i];
			if(e){
				e = this.getElement(e);
				if(fn.call(scope || e, e, me, i) === false){
					break;
				}
			}
		}
		return me;
	},


	fill : function(els){
		var me = this;
		me.elements = [];
		me.add(els);
		return me;
	},


	filter : function(selector){
		var els = [],
		me = this,
		fn = Ext.isFunction(selector) ? selector
		: function(el){
			return el.is(selector);
		};

		me.each(function(el, self, i) {
			if (fn(el, i) !== false) {
				els[els.length] = me.transformElement(el);
			}
		});

		me.elements = els;
		return me;
	},


	indexOf : function(el){
		return this.elements.indexOf(this.transformElement(el));
	},


	replaceElement : function(el, replacement, domReplace){
		var index = !isNaN(el) ? el : this.indexOf(el),
		d;
		if(index > -1){
			replacement = Ext.getDom(replacement);
			if(domReplace){
				d = this.elements[index];
				d.parentNode.insertBefore(replacement, d);
				Ext.removeNode(d);
			}
			this.elements.splice(index, 1, replacement);
		}
		return this;
	},


	clear : function(){
		this.elements = [];
	}
};

Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addListener;


Ext.CompositeElementLite.importElementMethods = function() {
	var fnName,
	ElProto = Ext.Element.prototype,
	CelProto = Ext.CompositeElementLite.prototype;

	for (fnName in ElProto) {
		if (typeof ElProto[fnName] == 'function'){
			(function(fnName) {
				CelProto[fnName] = CelProto[fnName] || function() {
					return this.invoke(fnName, arguments);
				};
			}).call(CelProto, fnName);

		}
	}
};

Ext.CompositeElementLite.importElementMethods();

if(Ext.DomQuery){
	Ext.Element.selectorFunction = Ext.DomQuery.select;
}


Ext.Element.select = function(selector, root){
	var els;
	if(typeof selector == "string"){
		els = Ext.Element.selectorFunction(selector, root);
	}else if(selector.length !== undefined){
		els = selector;
	}else{
		throw "Invalid selector";
	}
	return new Ext.CompositeElementLite(els);
};

Ext.select = Ext.Element.select;
(function(){
	var BEFOREREQUEST = "beforerequest",
	REQUESTCOMPLETE = "requestcomplete",
	REQUESTEXCEPTION = "requestexception",
	UNDEFINED = undefined,
	LOAD = 'load',
	POST = 'POST',
	GET = 'GET',
	WINDOW = window;


	Ext.data.Connection = function(config){
		Ext.apply(this, config);
		this.addEvents(

			BEFOREREQUEST,

			REQUESTCOMPLETE,

			REQUESTEXCEPTION
			);
		Ext.data.Connection.superclass.constructor.call(this);
	};

	Ext.extend(Ext.data.Connection, Ext.util.Observable, {





		timeout : 30000,

		autoAbort:false,


		disableCaching: true,


		disableCachingParam: '_dc',


		request : function(o){
			var me = this;
			if(me.fireEvent(BEFOREREQUEST, me, o)){
				if (o.el) {
					if(!Ext.isEmpty(o.indicatorText)){
						me.indicatorText = '<div class="loading-indicator">'+o.indicatorText+"</div>";
					}
					if(me.indicatorText) {
						Ext.getDom(o.el).innerHTML = me.indicatorText;
					}
					o.success = (Ext.isFunction(o.success) ? o.success : function(){}).createInterceptor(function(response) {
						Ext.getDom(o.el).innerHTML = response.responseText;
					});
				}

				var p = o.params,
				url = o.url || me.url,
				method,
				cb = {
					success: me.handleResponse,
					failure: me.handleFailure,
					scope: me,
					argument: {
						options: o
					},
					timeout : Ext.num(o.timeout, me.timeout)
				},
				form,
				serForm;


				if (Ext.isFunction(p)) {
					p = p.call(o.scope||WINDOW, o);
				}

				p = Ext.urlEncode(me.extraParams, Ext.isObject(p) ? Ext.urlEncode(p) : p);

				if (Ext.isFunction(url)) {
					url = url.call(o.scope || WINDOW, o);
				}

				if((form = Ext.getDom(o.form))){
					url = url || form.action;
					if(o.isUpload || (/multipart\/form-data/i.test(form.getAttribute("enctype")))) {
						return me.doFormUpload.call(me, o, p, url);
					}
					serForm = Ext.lib.Ajax.serializeForm(form);
					p = p ? (p + '&' + serForm) : serForm;
				}

				method = o.method || me.method || ((p || o.xmlData || o.jsonData) ? POST : GET);

				if(method === GET && (me.disableCaching && o.disableCaching !== false) || o.disableCaching === true){
					var dcp = o.disableCachingParam || me.disableCachingParam;
					url = Ext.urlAppend(url, dcp + '=' + (new Date().getTime()));
				}

				o.headers = Ext.apply(o.headers || {}, me.defaultHeaders || {});

				if(o.autoAbort === true || me.autoAbort) {
					me.abort();
				}

				if((method == GET || o.xmlData || o.jsonData) && p){
					url = Ext.urlAppend(url, p);
					p = '';
				}
				return (me.transId = Ext.lib.Ajax.request(method, url, cb, p, o));
			}else{
				return o.callback ? o.callback.apply(o.scope, [o,UNDEFINED,UNDEFINED]) : null;
			}
		},


		isLoading : function(transId){
			return transId ? Ext.lib.Ajax.isCallInProgress(transId) : !! this.transId;
		},


		abort : function(transId){
			if(transId || this.isLoading()){
				Ext.lib.Ajax.abort(transId || this.transId);
			}
		},


		handleResponse : function(response){
			this.transId = false;
			var options = response.argument.options;
			response.argument = options ? options.argument : null;
			this.fireEvent(REQUESTCOMPLETE, this, response, options);
			if(options.success){
				options.success.call(options.scope, response, options);
			}
			if(options.callback){
				options.callback.call(options.scope, options, true, response);
			}
		},


		handleFailure : function(response, e){
			this.transId = false;
			var options = response.argument.options;
			response.argument = options ? options.argument : null;
			this.fireEvent(REQUESTEXCEPTION, this, response, options, e);
			if(options.failure){
				options.failure.call(options.scope, response, options);
			}
			if(options.callback){
				options.callback.call(options.scope, options, false, response);
			}
		},


		doFormUpload : function(o, ps, url){
			var id = Ext.id(),
			doc = document,
			frame = doc.createElement('iframe'),
			form = Ext.getDom(o.form),
			hiddens = [],
			hd,
			encoding = 'multipart/form-data',
			buf = {
				target: form.target,
				method: form.method,
				encoding: form.encoding,
				enctype: form.enctype,
				action: form.action
			};


			Ext.fly(frame).set({
				id: id,
				name: id,
				cls: 'x-hidden',
				src: Ext.SSL_SECURE_URL
			});

			doc.body.appendChild(frame);


			if(Ext.isIE){
				document.frames[id].name = id;
			}


			Ext.fly(form).set({
				target: id,
				method: POST,
				enctype: encoding,
				encoding: encoding,
				action: url || buf.action
			});


			Ext.iterate(Ext.urlDecode(ps, false), function(k, v){
				hd = doc.createElement('input');
				Ext.fly(hd).set({
					type: 'hidden',
					value: v,
					name: k
				});
				form.appendChild(hd);
				hiddens.push(hd);
			});

			function cb(){
				var me = this,

				r = {
					responseText : '',
					responseXML : null,
					argument : o.argument
					},
				doc,
				firstChild;

				try{
					doc = frame.contentWindow.document || frame.contentDocument || WINDOW.frames[id].document;
					if(doc){
						if(doc.body){
							if(/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)){
								r.responseText = firstChild.value;
							}else{
								r.responseText = doc.body.innerHTML;
							}
						}

						r.responseXML = doc.XMLDocument || doc;
					}
				}
				catch(e) {}

				Ext.EventManager.removeListener(frame, LOAD, cb, me);

				me.fireEvent(REQUESTCOMPLETE, me, r, o);

				function runCallback(fn, scope, args){
					if(Ext.isFunction(fn)){
						fn.apply(scope, args);
					}
				}

				runCallback(o.success, o.scope, [r, o]);
				runCallback(o.callback, o.scope, [o, true, r]);

				if(!me.debugUploads){
					setTimeout(function(){
						Ext.removeNode(frame);
					}, 100);
				}
			}

			Ext.EventManager.on(frame, LOAD, cb, this);
			form.submit();

			Ext.fly(form).set(buf);
			Ext.each(hiddens, function(h) {
				Ext.removeNode(h);
			});
		}
	});
})();


Ext.Ajax = new Ext.data.Connection({

















	autoAbort : false,


	serializeForm : function(form){
		return Ext.lib.Ajax.serializeForm(form);
	}
});

Ext.util.JSON = new (function(){
	var useHasOwn = !!{}.hasOwnProperty,
	isNative = function() {
		var useNative = null;

		return function() {
			if (useNative === null) {
				useNative = Ext.USE_NATIVE_JSON && window.JSON && JSON.toString() == '[object JSON]';
			}

			return useNative;
		};
	}(),
	pad = function(n) {
		return n < 10 ? "0" + n : n;
	},
	doDecode = function(json){
		return eval("(" + json + ")");
	},
	doEncode = function(o){
		if(!Ext.isDefined(o) || o === null){
			return "null";
		}else if(Ext.isArray(o)){
			return encodeArray(o);
		}else if(Ext.isDate(o)){
			return Ext.util.JSON.encodeDate(o);
		}else if(Ext.isString(o)){
			return encodeString(o);
		}else if(typeof o == "number"){

			return isFinite(o) ? String(o) : "null";
		}else if(Ext.isBoolean(o)){
			return String(o);
		}else {
			var a = ["{"], b, i, v;
			for (i in o) {

				if(!o.getElementsByTagName){
					if(!useHasOwn || o.hasOwnProperty(i)) {
						v = o[i];
						switch (typeof v) {
							case "undefined":
							case "function":
							case "unknown":
								break;
							default:
								if(b){
									a.push(',');
								}
								a.push(doEncode(i), ":",
									v === null ? "null" : doEncode(v));
								b = true;
						}
					}
				}
			}
			a.push("}");
			return a.join("");
		}
	},
	m = {
		"\b": '\\b',
		"\t": '\\t',
		"\n": '\\n',
		"\f": '\\f',
		"\r": '\\r',
		'"' : '\\"',
		"\\": '\\\\'
	},
	encodeString = function(s){
		if (/["\\\x00-\x1f]/.test(s)) {
			return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
				var c = m[b];
				if(c){
					return c;
				}
				c = b.charCodeAt();
				return "\\u00" +
				Math.floor(c / 16).toString(16) +
				(c % 16).toString(16);
			}) + '"';
		}
		return '"' + s + '"';
	},
	encodeArray = function(o){
		var a = ["["], b, i, l = o.length, v;
		for (i = 0; i < l; i += 1) {
			v = o[i];
			switch (typeof v) {
				case "undefined":
				case "function":
				case "unknown":
					break;
				default:
					if (b) {
						a.push(',');
					}
					a.push(v === null ? "null" : Ext.util.JSON.encode(v));
					b = true;
			}
		}
		a.push("]");
		return a.join("");
	};


	this.encodeDate = function(o){
		return '"' + o.getFullYear() + "-" +
		pad(o.getMonth() + 1) + "-" +
		pad(o.getDate()) + "T" +
		pad(o.getHours()) + ":" +
		pad(o.getMinutes()) + ":" +
		pad(o.getSeconds()) + '"';
	};


	this.encode = function() {
		var ec;
		return function(o) {
			if (!ec) {

				ec = isNative() ? JSON.stringify : doEncode;
			}
			return ec(o);
		};
	}();



	this.decode = function() {
		var dc;
		return function(json) {
			if (!dc) {

				dc = isNative() ? JSON.parse : doDecode;
			}
			return dc(json);
		};
	}();

})();

Ext.encode = Ext.util.JSON.encode;

Ext.decode = Ext.util.JSON.decode;

Ext.EventManager = function(){
	var docReadyEvent,
	docReadyProcId,
	docReadyState = false,
	DETECT_NATIVE = Ext.isGecko || Ext.isWebKit || Ext.isSafari,
	E = Ext.lib.Event,
	D = Ext.lib.Dom,
	DOC = document,
	WINDOW = window,
	DOMCONTENTLOADED = "DOMContentLoaded",
	COMPLETE = 'complete',
	propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,

	specialElCache = [];

	function getId(el){
		var id = false,
		i = 0,
		len = specialElCache.length,
		skip = false,
		o;

		if (el) {
			if (el.getElementById || el.navigator) {

				for(; i < len; ++i){
					o = specialElCache[i];
					if(o.el === el){
						id = o.id;
						break;
					}
				}
				if(!id){

					id = Ext.id(el);
					specialElCache.push({
						id: id,
						el: el
					});
					skip = true;
				}
			}else{
				id = Ext.id(el);
			}
			if(!Ext.elCache[id]){
				Ext.Element.addToCache(new Ext.Element(el), id);
				if(skip){
					Ext.elCache[id].skipGC = true;
				}
			}
		}
		return id;
	}


	function addListener(el, ename, fn, task, wrap, scope){
		el = Ext.getDom(el);
		var id = getId(el),
		es = Ext.elCache[id].events,
		wfn;

		wfn = E.on(el, ename, wrap);
		es[ename] = es[ename] || [];


		es[ename].push([fn, wrap, scope, wfn, task]);





		if(el.addEventListener && ename == "mousewheel"){
			var args = ["DOMMouseScroll", wrap, false];
			el.addEventListener.apply(el, args);
			Ext.EventManager.addListener(WINDOW, 'unload', function(){
				el.removeEventListener.apply(el, args);
			});
		}


		if(el == DOC && ename == "mousedown"){
			Ext.EventManager.stoppedMouseDownEvent.addListener(wrap);
		}
	}

	function doScrollChk(){

		if(window != top){
			return false;
		}

		try{
			DOC.documentElement.doScroll('left');
		}catch(e){
			return false;
		}

		fireDocReady();
		return true;
	}

	function checkReadyState(e){

		if(Ext.isIE && doScrollChk()){
			return true;
		}
		if(DOC.readyState == COMPLETE){
			fireDocReady();
			return true;
		}
		docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2));
		return false;
	}

	var styles;
	function checkStyleSheets(e){
		styles || (styles = Ext.query('style, link[rel=stylesheet]'));
		if(styles.length == DOC.styleSheets.length){
			fireDocReady();
			return true;
		}
		docReadyState || (docReadyProcId = setTimeout(arguments.callee, 2));
		return false;
	}

	function OperaDOMContentLoaded(e){
		DOC.removeEventListener(DOMCONTENTLOADED, arguments.callee, false);
		checkStyleSheets();
	}

	function fireDocReady(e){
		if(!docReadyState){
			docReadyState = true;

			if(docReadyProcId){
				clearTimeout(docReadyProcId);
			}
			if(DETECT_NATIVE) {
				DOC.removeEventListener(DOMCONTENTLOADED, fireDocReady, false);
			}
			if(Ext.isIE && checkReadyState.bindIE){
				DOC.detachEvent('onreadystatechange', checkReadyState);
			}
			E.un(WINDOW, "load", arguments.callee);
		}
		if(docReadyEvent && !Ext.isReady){
			Ext.isReady = true;
			docReadyEvent.fire();
			docReadyEvent.listeners = [];
		}

	}

	function initDocReady(){
		docReadyEvent || (docReadyEvent = new Ext.util.Event());
		if (DETECT_NATIVE) {
			DOC.addEventListener(DOMCONTENTLOADED, fireDocReady, false);
		}

		if (Ext.isIE){


			if(!checkReadyState()){
				checkReadyState.bindIE = true;
				DOC.attachEvent('onreadystatechange', checkReadyState);
			}

		}else if(Ext.isOpera ){



			(DOC.readyState == COMPLETE && checkStyleSheets()) ||
			DOC.addEventListener(DOMCONTENTLOADED, OperaDOMContentLoaded, false);

		}else if (Ext.isWebKit){

			checkReadyState();
		}

		E.on(WINDOW, "load", fireDocReady);
	}

	function createTargeted(h, o){
		return function(){
			var args = Ext.toArray(arguments);
			if(o.target == Ext.EventObject.setEvent(args[0]).target){
				h.apply(this, args);
			}
		};
	}

	function createBuffered(h, o, task){
		return function(e){

			task.delay(o.buffer, h, null, [new Ext.EventObjectImpl(e)]);
		};
	}

	function createSingle(h, el, ename, fn, scope){
		return function(e){
			Ext.EventManager.removeListener(el, ename, fn, scope);
			h(e);
		};
	}

	function createDelayed(h, o, fn){
		return function(e){
			var task = new Ext.util.DelayedTask(h);
			if(!fn.tasks) {
				fn.tasks = [];
			}
			fn.tasks.push(task);
			task.delay(o.delay || 10, h, null, [new Ext.EventObjectImpl(e)]);
		};
	}

	function listen(element, ename, opt, fn, scope){
		var o = (!opt || typeof opt == "boolean") ? {} : opt,
		el = Ext.getDom(element), task;

		fn = fn || o.fn;
		scope = scope || o.scope;

		if(!el){
			throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';
		}
		function h(e){

			if(!Ext){
				return;
			}
			e = Ext.EventObject.setEvent(e);
			var t;
			if (o.delegate) {
				if(!(t = e.getTarget(o.delegate, el))){
					return;
				}
			} else {
				t = e.target;
			}
			if (o.stopEvent) {
				e.stopEvent();
			}
			if (o.preventDefault) {
				e.preventDefault();
			}
			if (o.stopPropagation) {
				e.stopPropagation();
			}
			if (o.normalized === false) {
				e = e.browserEvent;
			}

			fn.call(scope || el, e, t, o);
		}
		if(o.target){
			h = createTargeted(h, o);
		}
		if(o.delay){
			h = createDelayed(h, o, fn);
		}
		if(o.single){
			h = createSingle(h, el, ename, fn, scope);
		}
		if(o.buffer){
			task = new Ext.util.DelayedTask(h);
			h = createBuffered(h, o, task);
		}

		addListener(el, ename, fn, task, h, scope);
		return h;
	}

	var pub = {

		addListener : function(element, eventName, fn, scope, options){
			if(typeof eventName == 'object'){
				var o = eventName, e, val;
				for(e in o){
					val = o[e];
					if(!propRe.test(e)){
						if(Ext.isFunction(val)){

							listen(element, e, o, val, o.scope);
						}else{

							listen(element, e, val);
						}
					}
				}
			} else {
				listen(element, eventName, options, fn, scope);
			}
		},


		removeListener : function(el, eventName, fn, scope){
			el = Ext.getDom(el);
			var id = getId(el),
			f = el && (Ext.elCache[id].events)[eventName] || [],
			wrap, i, l, k, len, fnc;

			for (i = 0, len = f.length; i < len; i++) {


				if (Ext.isArray(fnc = f[i]) && fnc[0] == fn && (!scope || fnc[2] == scope)) {
					if(fnc[4]) {
						fnc[4].cancel();
					}
					k = fn.tasks && fn.tasks.length;
					if(k) {
						while(k--) {
							fn.tasks[k].cancel();
						}
						delete fn.tasks;
					}
					wrap = fnc[1];
					E.un(el, eventName, E.extAdapter ? fnc[3] : wrap);


					if(wrap && el.addEventListener && eventName == "mousewheel"){
						el.removeEventListener("DOMMouseScroll", wrap, false);
					}


					if(wrap && el == DOC && eventName == "mousedown"){
						Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
					}

					f.splice(i, 1);
					if (f.length === 0) {
						delete Ext.elCache[id].events[eventName];
					}
					for (k in Ext.elCache[id].events) {
						return false;
					}
					Ext.elCache[id].events = {};
					return false;
				}
			}
		},


		removeAll : function(el){
			el = Ext.getDom(el);
			var id = getId(el),
			ec = Ext.elCache[id] || {},
			es = ec.events || {},
			f, i, len, ename, fn, k, wrap;

			for(ename in es){
				if(es.hasOwnProperty(ename)){
					f = es[ename];

					for (i = 0, len = f.length; i < len; i++) {
						fn = f[i];
						if(fn[4]) {
							fn[4].cancel();
						}
						if(fn[0].tasks && (k = fn[0].tasks.length)) {
							while(k--) {
								fn[0].tasks[k].cancel();
							}
							delete fn.tasks;
						}
						wrap =  fn[1];
						E.un(el, ename, E.extAdapter ? fn[3] : wrap);


						if(el.addEventListener && wrap && ename == "mousewheel"){
							el.removeEventListener("DOMMouseScroll", wrap, false);
						}


						if(wrap && el == DOC &&  ename == "mousedown"){
							Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
						}
					}
				}
			}
			if (Ext.elCache[id]) {
				Ext.elCache[id].events = {};
			}
		},

		getListeners : function(el, eventName) {
			el = Ext.getDom(el);
			var id = getId(el),
			ec = Ext.elCache[id] || {},
			es = ec.events || {},
			results = [];
			if (es && es[eventName]) {
				return es[eventName];
			} else {
				return null;
			}
		},

		purgeElement : function(el, recurse, eventName) {
			el = Ext.getDom(el);
			var id = getId(el),
			ec = Ext.elCache[id] || {},
			es = ec.events || {},
			i, f, len;
			if (eventName) {
				if (es && es.hasOwnProperty(eventName)) {
					f = es[eventName];
					for (i = 0, len = f.length; i < len; i++) {
						Ext.EventManager.removeListener(el, eventName, f[i][0]);
					}
				}
			} else {
				Ext.EventManager.removeAll(el);
			}
			if (recurse && el && el.childNodes) {
				for (i = 0, len = el.childNodes.length; i < len; i++) {
					Ext.EventManager.purgeElement(el.childNodes[i], recurse, eventName);
				}
			}
		},

		_unload : function() {
			var el;
			for (el in Ext.elCache) {
				Ext.EventManager.removeAll(el);
			}
			delete Ext.elCache;
			delete Ext.Element._flyweights;


			var c,
			conn,
			tid,
			ajax = Ext.lib.Ajax;
			(typeof ajax.conn == 'object') ? conn = ajax.conn : conn = {};
			for (tid in conn) {
				c = conn[tid];
				if (c) {
					ajax.abort({
						conn: c,
						tId: tid
					});
				}
			}
		},

		onDocumentReady : function(fn, scope, options){
			if (Ext.isReady) {
				docReadyEvent || (docReadyEvent = new Ext.util.Event());
				docReadyEvent.addListener(fn, scope, options);
				docReadyEvent.fire();
				docReadyEvent.listeners = [];
			} else {
				if (!docReadyEvent) {
					initDocReady();
				}
				options = options || {};
				options.delay = options.delay || 1;
				docReadyEvent.addListener(fn, scope, options);
			}
		},


		fireDocReady  : fireDocReady
	};

	pub.on = pub.addListener;

	pub.un = pub.removeListener;

	pub.stoppedMouseDownEvent = new Ext.util.Event();
	return pub;
}();

Ext.onReady = Ext.EventManager.onDocumentReady;



(function(){
	var initExtCss = function() {

		var bd = document.body || document.getElementsByTagName('body')[0];
		if (!bd) {
			return false;
		}

		var cls = [' ',
		Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : (Ext.isIE7 ? 'ext-ie7' : 'ext-ie8'))
		: Ext.isGecko ? "ext-gecko " + (Ext.isGecko2 ? 'ext-gecko2' : 'ext-gecko3')
		: Ext.isOpera ? "ext-opera"
		: Ext.isWebKit ? "ext-webkit" : ""];

		if (Ext.isSafari) {
			cls.push("ext-safari " + (Ext.isSafari2 ? 'ext-safari2' : (Ext.isSafari3 ? 'ext-safari3' : 'ext-safari4')));
		} else if(Ext.isChrome) {
			cls.push("ext-chrome");
		}

		if (Ext.isMac) {
			cls.push("ext-mac");
		}
		if (Ext.isLinux) {
			cls.push("ext-linux");
		}


		if (Ext.isStrict || Ext.isBorderBox) {
			var p = bd.parentNode;
			if (p) {
				Ext.fly(p, '_internal').addClass(((Ext.isStrict && Ext.isIE ) || (!Ext.enableForcedBoxModel && !Ext.isIE)) ? ' ext-strict' : ' ext-border-box');
			}
		}


		if (Ext.enableForcedBoxModel && !Ext.isIE) {
			Ext.isForcedBorderBox = true;
			cls.push("ext-forced-border-box");
		}

		Ext.fly(bd, '_internal').addClass(cls);
		return true;
	};

	if (!initExtCss()) {
		Ext.onReady(initExtCss);
	}
})();


(function(){
	var supports = Ext.apply(Ext.supports, {

		correctRightMargin: true,


		correctTransparentColor: true,


		cssFloat: true
	});

	var supportTests = function(){
		var div = document.createElement('div'),
		doc = document,
		view,
		last;

		div.innerHTML = '<div style="height:30px;width:50px;"><div style="height:20px;width:20px;"></div></div><div style="float:left;background-color:transparent;">';
		doc.body.appendChild(div);
		last = div.lastChild;

		if((view = doc.defaultView)){
			if(view.getComputedStyle(div.firstChild.firstChild, null).marginRight != '0px'){
				supports.correctRightMargin = false;
			}
			if(view.getComputedStyle(last, null).backgroundColor != 'transparent'){
				supports.correctTransparentColor = false;
			}
		}
		supports.cssFloat = !!last.style.cssFloat;
		doc.body.removeChild(div);
	};

	if (Ext.isReady) {
		supportTests();
	} else {
		Ext.onReady(supportTests);
	}
})();



Ext.EventObject = function(){
	var E = Ext.lib.Event,
	clickRe = /(dbl)?click/,

	safariKeys = {
		3 : 13,
		63234 : 37,
		63235 : 39,
		63232 : 38,
		63233 : 40,
		63276 : 33,
		63277 : 34,
		63272 : 46,
		63273 : 36,
		63275 : 35
	},

	btnMap = Ext.isIE ? {
		1:0,
		4:1,
		2:2
	} : {
		0:0,
		1:1,
		2:2
	};

	Ext.EventObjectImpl = function(e){
		if(e){
			this.setEvent(e.browserEvent || e);
		}
	};

	Ext.EventObjectImpl.prototype = {

		setEvent : function(e){
			var me = this;
			if(e == me || (e && e.browserEvent)){
				return e;
			}
			me.browserEvent = e;
			if(e){

				me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1);
				if(clickRe.test(e.type) && me.button == -1){
					me.button = 0;
				}
				me.type = e.type;
				me.shiftKey = e.shiftKey;

				me.ctrlKey = e.ctrlKey || e.metaKey || false;
				me.altKey = e.altKey;

				me.keyCode = e.keyCode;
				me.charCode = e.charCode;

				me.target = E.getTarget(e);

				me.xy = E.getXY(e);
			}else{
				me.button = -1;
				me.shiftKey = false;
				me.ctrlKey = false;
				me.altKey = false;
				me.keyCode = 0;
				me.charCode = 0;
				me.target = null;
				me.xy = [0, 0];
			}
			return me;
		},


		stopEvent : function(){
			var me = this;
			if(me.browserEvent){
				if(me.browserEvent.type == 'mousedown'){
					Ext.EventManager.stoppedMouseDownEvent.fire(me);
				}
				E.stopEvent(me.browserEvent);
			}
		},


		preventDefault : function(){
			if(this.browserEvent){
				E.preventDefault(this.browserEvent);
			}
		},


		stopPropagation : function(){
			var me = this;
			if(me.browserEvent){
				if(me.browserEvent.type == 'mousedown'){
					Ext.EventManager.stoppedMouseDownEvent.fire(me);
				}
				E.stopPropagation(me.browserEvent);
			}
		},


		getCharCode : function(){
			return this.charCode || this.keyCode;
		},


		getKey : function(){
			return this.normalizeKey(this.keyCode || this.charCode);
		},


		normalizeKey: function(k){
			return Ext.isSafari ? (safariKeys[k] || k) : k;
		},


		getPageX : function(){
			return this.xy[0];
		},


		getPageY : function(){
			return this.xy[1];
		},


		getXY : function(){
			return this.xy;
		},


		getTarget : function(selector, maxDepth, returnEl){
			return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target);
		},


		getRelatedTarget : function(){
			return this.browserEvent ? E.getRelatedTarget(this.browserEvent) : null;
		},


		getWheelDelta : function(){
			var e = this.browserEvent;
			var delta = 0;
			if(e.wheelDelta){
				delta = e.wheelDelta/120;
			}else if(e.detail){
				delta = -e.detail/3;
			}
			return delta;
		},


		within : function(el, related, allowEl){
			if(el){
				var t = this[related ? "getRelatedTarget" : "getTarget"]();
				return t && ((allowEl ? (t == Ext.getDom(el)) : false) || Ext.fly(el).contains(t));
			}
			return false;
		}
	};

	return new Ext.EventObjectImpl();
}();

Ext.Loader = Ext.apply({}, {

	load: function(fileList, callback, scope, preserveOrder) {
		var scope       = scope || this,
		head        = document.getElementsByTagName("head")[0],
		fragment    = document.createDocumentFragment(),
		numFiles    = fileList.length,
		loadedFiles = 0,
		me          = this;


		var loadFileIndex = function(index) {
			head.appendChild(
				me.buildScriptTag(fileList[index], onFileLoaded)
				);
		};


		var onFileLoaded = function() {
			loadedFiles ++;


			if (numFiles == loadedFiles && typeof callback == 'function') {
				callback.call(scope);
			} else {
				if (preserveOrder === true) {
					loadFileIndex(loadedFiles);
				}
			}
		};

		if (preserveOrder === true) {
			loadFileIndex.call(this, 0);
		} else {

			Ext.each(fileList, function(file, index) {
				fragment.appendChild(
					this.buildScriptTag(file, onFileLoaded)
					);
			}, this);

			head.appendChild(fragment);
		}
	},


	buildScriptTag: function(filename, callback) {
		var script  = document.createElement('script');
		script.type = "text/javascript";
		script.src  = filename;


		if (script.readyState) {
			script.onreadystatechange = function() {
				if (script.readyState == "loaded" || script.readyState == "complete") {
					script.onreadystatechange = null;
					callback();
				}
			};
		} else {
			script.onload = callback;
		}

		return script;
	}
});


Ext.ns("Ext.grid", "Ext.list", "Ext.dd", "Ext.tree", "Ext.form", "Ext.menu",
	"Ext.state", "Ext.layout", "Ext.app", "Ext.ux", "Ext.chart", "Ext.direct");


Ext.apply(Ext, function(){
	var E = Ext,
	idSeed = 0,
	scrollWidth = null;

	return {

		emptyFn : function(){},


		BLANK_IMAGE_URL : Ext.isIE6 || Ext.isIE7 || Ext.isAir ?
		'http:/' + '/www.extjs.com/s.gif' :
		'',

		extendX : function(supr, fn){
			return Ext.extend(supr, fn(supr.prototype));
		},


		getDoc : function(){
			return Ext.get(document);
		},


		num : function(v, defaultValue){
			v = Number(Ext.isEmpty(v) || Ext.isArray(v) || typeof v == 'boolean' || (typeof v == 'string' && v.trim().length == 0) ? NaN : v);
			return isNaN(v) ? defaultValue : v;
		},


		value : function(v, defaultValue, allowBlank){
			return Ext.isEmpty(v, allowBlank) ? defaultValue : v;
		},


		escapeRe : function(s) {
			return s.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1");
		},

		sequence : function(o, name, fn, scope){
			o[name] = o[name].createSequence(fn, scope);
		},


		addBehaviors : function(o){
			if(!Ext.isReady){
				Ext.onReady(function(){
					Ext.addBehaviors(o);
				});
			} else {
				var cache = {},
				parts,
				b,
				s;
				for (b in o) {
					if ((parts = b.split('@'))[1]) {
						s = parts[0];
						if(!cache[s]){
							cache[s] = Ext.select(s);
						}
						cache[s].on(parts[1], o[b]);
					}
				}
				cache = null;
			}
		},


		getScrollBarWidth: function(force){
			if(!Ext.isReady){
				return 0;
			}

			if(force === true || scrollWidth === null){

				var div = Ext.getBody().createChild('<div class="x-hide-offsets" style="width:100px;height:50px;overflow:hidden;"><div style="height:200px;"></div></div>'),
				child = div.child('div', true);
				var w1 = child.offsetWidth;
				div.setStyle('overflow', (Ext.isWebKit || Ext.isGecko) ? 'auto' : 'scroll');
				var w2 = child.offsetWidth;
				div.remove();

				scrollWidth = w1 - w2 + 2;
			}
			return scrollWidth;
		},



		combine : function(){
			var as = arguments, l = as.length, r = [];
			for(var i = 0; i < l; i++){
				var a = as[i];
				if(Ext.isArray(a)){
					r = r.concat(a);
				}else if(a.length !== undefined && !a.substr){
					r = r.concat(Array.prototype.slice.call(a, 0));
				}else{
					r.push(a);
				}
			}
			return r;
		},


		copyTo : function(dest, source, names){
			if(typeof names == 'string'){
				names = names.split(/[,;\s]/);
			}
			Ext.each(names, function(name){
				if(source.hasOwnProperty(name)){
					dest[name] = source[name];
				}
			}, this);
			return dest;
		},


		destroy : function(){
			Ext.each(arguments, function(arg){
				if(arg){
					if(Ext.isArray(arg)){
						this.destroy.apply(this, arg);
					}else if(typeof arg.destroy == 'function'){
						arg.destroy();
					}else if(arg.dom){
						arg.remove();
					}
				}
			}, this);
		},


		destroyMembers : function(o, arg1, arg2, etc){
			for(var i = 1, a = arguments, len = a.length; i < len; i++) {
				Ext.destroy(o[a[i]]);
				delete o[a[i]];
			}
		},


		clean : function(arr){
			var ret = [];
			Ext.each(arr, function(v){
				if(!!v){
					ret.push(v);
				}
			});
			return ret;
		},


		unique : function(arr){
			var ret = [],
			collect = {};

			Ext.each(arr, function(v) {
				if(!collect[v]){
					ret.push(v);
				}
				collect[v] = true;
			});
			return ret;
		},


		flatten : function(arr){
			var worker = [];
			function rFlatten(a) {
				Ext.each(a, function(v) {
					if(Ext.isArray(v)){
						rFlatten(v);
					}else{
						worker.push(v);
					}
				});
				return worker;
			}
			return rFlatten(arr);
		},


		min : function(arr, comp){
			var ret = arr[0];
			comp = comp || function(a,b){
				return a < b ? -1 : 1;
			};
			Ext.each(arr, function(v) {
				ret = comp(ret, v) == -1 ? ret : v;
			});
			return ret;
		},


		max : function(arr, comp){
			var ret = arr[0];
			comp = comp || function(a,b){
				return a > b ? 1 : -1;
			};
			Ext.each(arr, function(v) {
				ret = comp(ret, v) == 1 ? ret : v;
			});
			return ret;
		},


		mean : function(arr){
			return arr.length > 0 ? Ext.sum(arr) / arr.length : undefined;
		},


		sum : function(arr){
			var ret = 0;
			Ext.each(arr, function(v) {
				ret += v;
			});
			return ret;
		},


		partition : function(arr, truth){
			var ret = [[],[]];
			Ext.each(arr, function(v, i, a) {
				ret[ (truth && truth(v, i, a)) || (!truth && v) ? 0 : 1].push(v);
			});
			return ret;
		},


		invoke : function(arr, methodName){
			var ret = [],
			args = Array.prototype.slice.call(arguments, 2);
			Ext.each(arr, function(v,i) {
				if (v && typeof v[methodName] == 'function') {
					ret.push(v[methodName].apply(v, args));
				} else {
					ret.push(undefined);
				}
			});
			return ret;
		},


		pluck : function(arr, prop){
			var ret = [];
			Ext.each(arr, function(v) {
				ret.push( v[prop] );
			});
			return ret;
		},


		zip : function(){
			var parts = Ext.partition(arguments, function( val ){
				return typeof val != 'function';
			}),
			arrs = parts[0],
			fn = parts[1][0],
			len = Ext.max(Ext.pluck(arrs, "length")),
			ret = [];

			for (var i = 0; i < len; i++) {
				ret[i] = [];
				if(fn){
					ret[i] = fn.apply(fn, Ext.pluck(arrs, i));
				}else{
					for (var j = 0, aLen = arrs.length; j < aLen; j++){
						ret[i].push( arrs[j][i] );
					}
				}
			}
			return ret;
		},


		getCmp : function(id){
			return Ext.ComponentMgr.get(id);
		},


		useShims: E.isIE6 || (E.isMac && E.isGecko2),



		type : function(o){
			if(o === undefined || o === null){
				return false;
			}
			if(o.htmlElement){
				return 'element';
			}
			var t = typeof o;
			if(t == 'object' && o.nodeName) {
				switch(o.nodeType) {
					case 1:
						return 'element';
					case 3:
						return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace';
				}
			}
			if(t == 'object' || t == 'function') {
				switch(o.constructor) {
					case Array:
						return 'array';
					case RegExp:
						return 'regexp';
					case Date:
						return 'date';
				}
				if(typeof o.length == 'number' && typeof o.item == 'function') {
					return 'nodelist';
				}
			}
			return t;
		},

		intercept : function(o, name, fn, scope){
			o[name] = o[name].createInterceptor(fn, scope);
		},


		callback : function(cb, scope, args, delay){
			if(typeof cb == 'function'){
				if(delay){
					cb.defer(delay, scope, args || []);
				}else{
					cb.apply(scope, args || []);
				}
			}
		}
	};
}());


Ext.apply(Function.prototype, {

	createSequence : function(fcn, scope){
		var method = this;
		return (typeof fcn != 'function') ?
		this :
		function(){
			var retval = method.apply(this || window, arguments);
			fcn.apply(scope || this || window, arguments);
			return retval;
		};
	}
});



Ext.applyIf(String, {


	escape : function(string) {
		return string.replace(/('|\\)/g, "\\$1");
	},


	leftPad : function (val, size, ch) {
		var result = String(val);
		if(!ch) {
			ch = " ";
		}
		while (result.length < size) {
			result = ch + result;
		}
		return result;
	}
});


String.prototype.toggle = function(value, other){
	return this == value ? other : value;
};


String.prototype.trim = function(){
	var re = /^\s+|\s+$/g;
	return function(){
		return this.replace(re, "");
	};
}();



Date.prototype.getElapsed = function(date) {
	return Math.abs((date || new Date()).getTime()-this.getTime());
};



Ext.applyIf(Number.prototype, {

	constrain : function(min, max){
		return Math.min(Math.max(this, min), max);
	}
});
Ext.lib.Dom.getRegion = function(el) {
	return Ext.lib.Region.getRegion(el);
};
Ext.lib.Region = function(t, r, b, l) {
	var me = this;
	me.top = t;
	me[1] = t;
	me.right = r;
	me.bottom = b;
	me.left = l;
	me[0] = l;
};

Ext.lib.Region.prototype = {
	contains : function(region) {
		var me = this;
		return ( region.left >= me.left &&
			region.right <= me.right &&
			region.top >= me.top &&
			region.bottom <= me.bottom );

	},

	getArea : function() {
		var me = this;
		return ( (me.bottom - me.top) * (me.right - me.left) );
	},

	intersect : function(region) {
		var me = this,
		t = Math.max(me.top, region.top),
		r = Math.min(me.right, region.right),
		b = Math.min(me.bottom, region.bottom),
		l = Math.max(me.left, region.left);

		if (b >= t && r >= l) {
			return new Ext.lib.Region(t, r, b, l);
		}
	},

	union : function(region) {
		var me = this,
		t = Math.min(me.top, region.top),
		r = Math.max(me.right, region.right),
		b = Math.max(me.bottom, region.bottom),
		l = Math.min(me.left, region.left);

		return new Ext.lib.Region(t, r, b, l);
	},

	constrainTo : function(r) {
		var me = this;
		me.top = me.top.constrain(r.top, r.bottom);
		me.bottom = me.bottom.constrain(r.top, r.bottom);
		me.left = me.left.constrain(r.left, r.right);
		me.right = me.right.constrain(r.left, r.right);
		return me;
	},

	adjust : function(t, l, b, r) {
		var me = this;
		me.top += t;
		me.left += l;
		me.right += r;
		me.bottom += b;
		return me;
	}
};

Ext.lib.Region.getRegion = function(el) {
	var p = Ext.lib.Dom.getXY(el),
	t = p[1],
	r = p[0] + el.offsetWidth,
	b = p[1] + el.offsetHeight,
	l = p[0];

	return new Ext.lib.Region(t, r, b, l);
};
Ext.lib.Point = function(x, y) {
	if (Ext.isArray(x)) {
		y = x[1];
		x = x[0];
	}
	var me = this;
	me.x = me.right = me.left = me[0] = x;
	me.y = me.top = me.bottom = me[1] = y;
};

Ext.lib.Point.prototype = new Ext.lib.Region();

Ext.apply(Ext.DomHelper,
	function(){
		var pub,
		afterbegin = 'afterbegin',
		afterend = 'afterend',
		beforebegin = 'beforebegin',
		beforeend = 'beforeend',
		confRe = /tag|children|cn|html$/i;


		function doInsert(el, o, returnElement, pos, sibling, append){
			el = Ext.getDom(el);
			var newNode;
			if (pub.useDom) {
				newNode = createDom(o, null);
				if (append) {
					el.appendChild(newNode);
				} else {
					(sibling == 'firstChild' ? el : el.parentNode).insertBefore(newNode, el[sibling] || el);
				}
			} else {
				newNode = Ext.DomHelper.insertHtml(pos, el, Ext.DomHelper.createHtml(o));
			}
			return returnElement ? Ext.get(newNode, true) : newNode;
		}



		function createDom(o, parentNode){
			var el,
			doc = document,
			useSet,
			attr,
			val,
			cn;

			if (Ext.isArray(o)) {
				el = doc.createDocumentFragment();
				for (var i = 0, l = o.length; i < l; i++) {
					createDom(o[i], el);
				}
			} else if (typeof o == 'string') {
				el = doc.createTextNode(o);
			} else {
				el = doc.createElement( o.tag || 'div' );
				useSet = !!el.setAttribute;
				for (var attr in o) {
					if(!confRe.test(attr)){
						val = o[attr];
						if(attr == 'cls'){
							el.className = val;
						}else{
							if(useSet){
								el.setAttribute(attr, val);
							}else{
								el[attr] = val;
							}
						}
					}
				}
				Ext.DomHelper.applyStyles(el, o.style);

				if ((cn = o.children || o.cn)) {
					createDom(cn, el);
				} else if (o.html) {
					el.innerHTML = o.html;
				}
			}
			if(parentNode){
				parentNode.appendChild(el);
			}
			return el;
		}

		pub = {

			createTemplate : function(o){
				var html = Ext.DomHelper.createHtml(o);
				return new Ext.Template(html);
			},


			useDom : false,


			insertBefore : function(el, o, returnElement){
				return doInsert(el, o, returnElement, beforebegin);
			},


			insertAfter : function(el, o, returnElement){
				return doInsert(el, o, returnElement, afterend, 'nextSibling');
			},


			insertFirst : function(el, o, returnElement){
				return doInsert(el, o, returnElement, afterbegin, 'firstChild');
			},


			append: function(el, o, returnElement){
				return doInsert(el, o, returnElement, beforeend, '', true);
			},


			createDom: createDom
		};
		return pub;
	}());

Ext.apply(Ext.Template.prototype, {

	disableFormats : false,



	re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
	argsRe : /^\s*['"](.*)["']\s*$/,
	compileARe : /\\/g,
	compileBRe : /(\r\n|\n)/g,
	compileCRe : /'/g,

	/**
     * Returns an HTML fragment of this template with the specified values applied.
     * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
     * @return {String} The HTML fragment
     * @hide repeat doc
     */
	applyTemplate : function(values){
		var me = this,
		useF = me.disableFormats !== true,
		fm = Ext.util.Format,
		tpl = me;

		if(me.compiled){
			return me.compiled(values);
		}
		function fn(m, name, format, args){
			if (format && useF) {
				if (format.substr(0, 5) == "this.") {
					return tpl.call(format.substr(5), values[name], values);
				} else {
					if (args) {
						// quoted values are required for strings in compiled templates,
						// but for non compiled we need to strip them
						// quoted reversed for jsmin
						var re = me.argsRe;
						args = args.split(',');
						for(var i = 0, len = args.length; i < len; i++){
							args[i] = args[i].replace(re, "$1");
						}
						args = [values[name]].concat(args);
					} else {
						args = [values[name]];
					}
					return fm[format].apply(fm, args);
				}
			} else {
				return values[name] !== undefined ? values[name] : "";
			}
		}
		return me.html.replace(me.re, fn);
	},

	/**
     * Compiles the template into an internal function, eliminating the RegEx overhead.
     * @return {Ext.Template} this
     * @hide repeat doc
     */
	compile : function(){
		var me = this,
		fm = Ext.util.Format,
		useF = me.disableFormats !== true,
		sep = Ext.isGecko ? "+" : ",",
		body;

		function fn(m, name, format, args){
			if(format && useF){
				args = args ? ',' + args : "";
				if(format.substr(0, 5) != "this."){
					format = "fm." + format + '(';
				}else{
					format = 'this.call("'+ format.substr(5) + '", ';
					args = ", values";
				}
			}else{
				args= '';
				format = "(values['" + name + "'] == undefined ? '' : ";
			}
			return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'";
		}

		// branched to use + in gecko and [].join() in others
		if(Ext.isGecko){
			body = "this.compiled = function(values){ return '" +
			me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn) +
			"';};";
		}else{
			body = ["this.compiled = function(values){ return ['"];
			body.push(me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn));
			body.push("'].join('');};");
			body = body.join('');
		}
		eval(body);
		return me;
	},

	// private function used to call members
	call : function(fnName, value, allValues){
		return this[fnName](value, allValues);
	}
});
Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
/**
 * @class Ext.util.Functions
 * @singleton
 */
Ext.util.Functions = {
	/**
     * Creates an interceptor function. The passed function is called before the original one. If it returns false,
     * the original one is not called. The resulting function returns the results of the original function.
     * The passed function is called with the parameters of the original function. Example usage:
     * <pre><code>
var sayHi = function(name){
    alert('Hi, ' + name);
}

sayHi('Fred'); // alerts "Hi, Fred"

// create a new function that validates input without
// directly modifying the original function:
var sayHiToFriend = Ext.createInterceptor(sayHi, function(name){
    return name == 'Brian';
});

sayHiToFriend('Fred');  // no alert
sayHiToFriend('Brian'); // alerts "Hi, Brian"
       </code></pre>
     * @param {Function} origFn The original function.
     * @param {Function} newFn The function to call before the original
     * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed.
     * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b>
     * @return {Function} The new function
     */
	createInterceptor: function(origFn, newFn, scope) {
		var method = origFn;
		if (!Ext.isFunction(newFn)) {
			return origFn;
		}
		else {
			return function() {
				var me = this,
				args = arguments;
				newFn.target = me;
				newFn.method = origFn;
				return (newFn.apply(scope || me || window, args) !== false) ?
				origFn.apply(me || window, args) :
				null;
			};
		}
	},

	/**
     * Creates a delegate (callback) that sets the scope to obj.
     * Call directly on any function. Example: <code>Ext.createDelegate(this.myFunction, this, [arg1, arg2])</code>
     * Will create a function that is automatically scoped to obj so that the <tt>this</tt> variable inside the
     * callback points to obj. Example usage:
     * <pre><code>
var sayHi = function(name){
    // Note this use of "this.text" here.  This function expects to
    // execute within a scope that contains a text property.  In this
    // example, the "this" variable is pointing to the btn object that
    // was passed in createDelegate below.
    alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
}

var btn = new Ext.Button({
    text: 'Say Hi',
    renderTo: Ext.getBody()
});

// This callback will execute in the scope of the
// button instance. Clicking the button alerts
// "Hi, Fred. You clicked the "Say Hi" button."
btn.on('click', Ext.createDelegate(sayHi, btn, ['Fred']));
       </code></pre>
     * @param {Function} fn The function to delegate.
     * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
     * <b>If omitted, defaults to the browser window.</b>
     * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
     * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
     * if a number the args are inserted at the specified position
     * @return {Function} The new function
     */
	createDelegate: function(fn, obj, args, appendArgs) {
		if (!Ext.isFunction(fn)) {
			return fn;
		}
		return function() {
			var callArgs = args || arguments;
			if (appendArgs === true) {
				callArgs = Array.prototype.slice.call(arguments, 0);
				callArgs = callArgs.concat(args);
			}
			else if (Ext.isNumber(appendArgs)) {
				callArgs = Array.prototype.slice.call(arguments, 0);
				// copy arguments first
				var applyArgs = [appendArgs, 0].concat(args);
				// create method call params
				Array.prototype.splice.apply(callArgs, applyArgs);
			// splice them in
			}
			return fn.apply(obj || window, callArgs);
		};
	},

	/**
     * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
     * <pre><code>
var sayHi = function(name){
    alert('Hi, ' + name);
}

// executes immediately:
sayHi('Fred');

// executes after 2 seconds:
Ext.defer(sayHi, 2000, this, ['Fred']);

// this syntax is sometimes useful for deferring
// execution of an anonymous function:
Ext.defer(function(){
    alert('Anonymous');
}, 100);
       </code></pre>
     * @param {Function} fn The function to defer.
     * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
     * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
     * <b>If omitted, defaults to the browser window.</b>
     * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
     * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
     * if a number the args are inserted at the specified position
     * @return {Number} The timeout id that can be used with clearTimeout
     */
	defer: function(fn, millis, obj, args, appendArgs) {
		fn = Ext.util.Functions.createDelegate(fn, obj, args, appendArgs);
		if (millis > 0) {
			return setTimeout(fn, millis);
		}
		fn();
		return 0;
	},


	/**
     * Create a combined function call sequence of the original function + the passed function.
     * The resulting function returns the results of the original function.
     * The passed fcn is called with the parameters of the original function. Example usage:
     *

var sayHi = function(name){
    alert('Hi, ' + name);
}

sayHi('Fred'); // alerts "Hi, Fred"

var sayGoodbye = Ext.createSequence(sayHi, function(name){
    alert('Bye, ' + name);
});

sayGoodbye('Fred'); // both alerts show

     * @param {Function} origFn The original function.
     * @param {Function} newFn The function to sequence
     * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed.
     * If omitted, defaults to the scope in which the original function is called or the browser window.
     * @return {Function} The new function
     */
	createSequence: function(origFn, newFn, scope) {
		if (!Ext.isFunction(newFn)) {
			return origFn;
		}
		else {
			return function() {
				var retval = origFn.apply(this || window, arguments);
				newFn.apply(scope || this || window, arguments);
				return retval;
			};
		}
	}
};

/**
 * Shorthand for {@link Ext.util.Functions#defer}
 * @param {Function} fn The function to defer.
 * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
 * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
 * <b>If omitted, defaults to the browser window.</b>
 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
 * if a number the args are inserted at the specified position
 * @return {Number} The timeout id that can be used with clearTimeout
 * @member Ext
 * @method defer
 */

Ext.defer = Ext.util.Functions.defer;

/**
 * Shorthand for {@link Ext.util.Functions#createInterceptor}
 * @param {Function} origFn The original function.
 * @param {Function} newFn The function to call before the original
 * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed.
 * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b>
 * @return {Function} The new function
 * @member Ext
 * @method defer
 */

Ext.createInterceptor = Ext.util.Functions.createInterceptor;

/**
 * Shorthand for {@link Ext.util.Functions#createSequence}
 * @param {Function} origFn The original function.
 * @param {Function} newFn The function to sequence
 * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed.
 * If omitted, defaults to the scope in which the original function is called or the browser window.
 * @return {Function} The new function
 * @member Ext
 * @method defer
 */

Ext.createSequence = Ext.util.Functions.createSequence;

/**
 * Shorthand for {@link Ext.util.Functions#createDelegate}
 * @param {Function} fn The function to delegate.
 * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
 * <b>If omitted, defaults to the browser window.</b>
 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
 * if a number the args are inserted at the specified position
 * @return {Function} The new function
 * @member Ext
 * @method defer
 */
Ext.createDelegate = Ext.util.Functions.createDelegate;
/**
 * @class Ext.util.Observable
 */
Ext.apply(Ext.util.Observable.prototype, function(){
	// this is considered experimental (along with beforeMethod, afterMethod, removeMethodListener?)
	// allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
	// private
	function getMethodEvent(method){
		var e = (this.methodEvents = this.methodEvents ||
		{})[method], returnValue, v, cancel, obj = this;

		if (!e) {
			this.methodEvents[method] = e = {};
			e.originalFn = this[method];
			e.methodName = method;
			e.before = [];
			e.after = [];

			var makeCall = function(fn, scope, args){
				if((v = fn.apply(scope || obj, args)) !== undefined){
					if (typeof v == 'object') {
						if(v.returnValue !== undefined){
							returnValue = v.returnValue;
						}else{
							returnValue = v;
						}
						cancel = !!v.cancel;
					}
					else
					if (v === false) {
						cancel = true;
					}
					else {
						returnValue = v;
					}
				}
			};

			this[method] = function(){
				var args = Array.prototype.slice.call(arguments, 0),
				b;
				returnValue = v = undefined;
				cancel = false;

				for(var i = 0, len = e.before.length; i < len; i++){
					b = e.before[i];
					makeCall(b.fn, b.scope, args);
					if (cancel) {
						return returnValue;
					}
				}

				if((v = e.originalFn.apply(obj, args)) !== undefined){
					returnValue = v;
				}

				for(var i = 0, len = e.after.length; i < len; i++){
					b = e.after[i];
					makeCall(b.fn, b.scope, args);
					if (cancel) {
						return returnValue;
					}
				}
				return returnValue;
			};
		}
		return e;
	}

	return {
		// these are considered experimental
		// allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
		// adds an 'interceptor' called before the original method
		beforeMethod : function(method, fn, scope){
			getMethodEvent.call(this, method).before.push({
				fn: fn,
				scope: scope
			});
		},

		// adds a 'sequence' called after the original method
		afterMethod : function(method, fn, scope){
			getMethodEvent.call(this, method).after.push({
				fn: fn,
				scope: scope
			});
		},

		removeMethodListener: function(method, fn, scope){
			var e = this.getMethodEvent(method);
			for(var i = 0, len = e.before.length; i < len; i++){
				if(e.before[i].fn == fn && e.before[i].scope == scope){
					e.before.splice(i, 1);
					return;
				}
			}
			for(var i = 0, len = e.after.length; i < len; i++){
				if(e.after[i].fn == fn && e.after[i].scope == scope){
					e.after.splice(i, 1);
					return;
				}
			}
		},

		/**
         * Relays selected events from the specified Observable as if the events were fired by <tt><b>this</b></tt>.
         * @param {Object} o The Observable whose events this object is to relay.
         * @param {Array} events Array of event names to relay.
         */
		relayEvents : function(o, events){
			var me = this;
			function createHandler(ename){
				return function(){
					return me.fireEvent.apply(me, [ename].concat(Array.prototype.slice.call(arguments, 0)));
				};
			}
			for(var i = 0, len = events.length; i < len; i++){
				var ename = events[i];
				me.events[ename] = me.events[ename] || true;
				o.on(ename, createHandler(ename), me);
			}
		},

		/**
         * <p>Enables events fired by this Observable to bubble up an owner hierarchy by calling
         * <code>this.getBubbleTarget()</code> if present. There is no implementation in the Observable base class.</p>
         * <p>This is commonly used by Ext.Components to bubble events to owner Containers. See {@link Ext.Component.getBubbleTarget}. The default
         * implementation in Ext.Component returns the Component's immediate owner. But if a known target is required, this can be overridden to
         * access the required target more quickly.</p>
         * <p>Example:</p><pre><code>
Ext.override(Ext.form.Field, {

    initComponent : Ext.form.Field.prototype.initComponent.createSequence(function() {
        this.enableBubble('change');
    }),


    getBubbleTarget : function() {
        if (!this.formPanel) {
            this.formPanel = this.findParentByType('form');
        }
        return this.formPanel;
    }
});

var myForm = new Ext.formPanel({
    title: 'User Details',
    items: [{
        ...
    }],
    listeners: {
        change: function() {

            myForm.header.setStyle('color', 'red');
        }
    }
});
</code></pre>
         * @param {String/Array} events The event name to bubble, or an Array of event names.
         */
		enableBubble : function(events){
			var me = this;
			if(!Ext.isEmpty(events)){
				events = Ext.isArray(events) ? events : Array.prototype.slice.call(arguments, 0);
				for(var i = 0, len = events.length; i < len; i++){
					var ename = events[i];
					ename = ename.toLowerCase();
					var ce = me.events[ename] || true;
					if (typeof ce == 'boolean') {
						ce = new Ext.util.Event(me, ename);
						me.events[ename] = ce;
					}
					ce.bubble = true;
				}
			}
		}
	};
}());



Ext.util.Observable.capture = function(o, fn, scope){
	o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
};



Ext.util.Observable.observeClass = function(c, listeners){
	if(c){
		if(!c.fireEvent){
			Ext.apply(c, new Ext.util.Observable());
			Ext.util.Observable.capture(c.prototype, c.fireEvent, c);
		}
		if(typeof listeners == 'object'){
			c.on(listeners);
		}
		return c;
	}
};

Ext.apply(Ext.EventManager, function(){
	var resizeEvent,
	resizeTask,
	textEvent,
	textSize,
	D = Ext.lib.Dom,
	propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
	curWidth = 0,
	curHeight = 0,



	useKeydown = Ext.isWebKit ?
	Ext.num(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1]) >= 525 :
	!((Ext.isGecko && !Ext.isWindows) || Ext.isOpera);

	return {

		doResizeEvent: function(){
			var h = D.getViewHeight(),
			w = D.getViewWidth();


			if(curHeight != h || curWidth != w){
				resizeEvent.fire(curWidth = w, curHeight = h);
			}
		},


		onWindowResize : function(fn, scope, options){
			if(!resizeEvent){
				resizeEvent = new Ext.util.Event();
				resizeTask = new Ext.util.DelayedTask(this.doResizeEvent);
				Ext.EventManager.on(window, "resize", this.fireWindowResize, this);
			}
			resizeEvent.addListener(fn, scope, options);
		},


		fireWindowResize : function(){
			if(resizeEvent){
				resizeTask.delay(100);
			}
		},


		onTextResize : function(fn, scope, options){
			if(!textEvent){
				textEvent = new Ext.util.Event();
				var textEl = new Ext.Element(document.createElement('div'));
				textEl.dom.className = 'x-text-resize';
				textEl.dom.innerHTML = 'X';
				textEl.appendTo(document.body);
				textSize = textEl.dom.offsetHeight;
				setInterval(function(){
					if(textEl.dom.offsetHeight != textSize){
						textEvent.fire(textSize, textSize = textEl.dom.offsetHeight);
					}
				}, this.textResizeInterval);
			}
			textEvent.addListener(fn, scope, options);
		},


		removeResizeListener : function(fn, scope){
			if(resizeEvent){
				resizeEvent.removeListener(fn, scope);
			}
		},


		fireResize : function(){
			if(resizeEvent){
				resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
			}
		},


		textResizeInterval : 50,


		ieDeferSrc : false,


		getKeyEvent : function(){
			return useKeydown ? 'keydown' : 'keypress';
		},



		useKeydown: useKeydown
	};
}());

Ext.EventManager.on = Ext.EventManager.addListener;


Ext.apply(Ext.EventObjectImpl.prototype, {

	BACKSPACE: 8,

	TAB: 9,

	NUM_CENTER: 12,

	ENTER: 13,

	RETURN: 13,

	SHIFT: 16,

	CTRL: 17,
	CONTROL : 17,

	ALT: 18,

	PAUSE: 19,

	CAPS_LOCK: 20,

	ESC: 27,

	SPACE: 32,

	PAGE_UP: 33,
	PAGEUP : 33,

	PAGE_DOWN: 34,
	PAGEDOWN : 34,

	END: 35,

	HOME: 36,

	LEFT: 37,

	UP: 38,

	RIGHT: 39,

	DOWN: 40,

	PRINT_SCREEN: 44,

	INSERT: 45,

	DELETE: 46,

	ZERO: 48,

	ONE: 49,

	TWO: 50,

	THREE: 51,

	FOUR: 52,

	FIVE: 53,

	SIX: 54,

	SEVEN: 55,

	EIGHT: 56,

	NINE: 57,

	A: 65,

	B: 66,

	C: 67,

	D: 68,

	E: 69,

	F: 70,

	G: 71,

	H: 72,

	I: 73,

	J: 74,

	K: 75,

	L: 76,

	M: 77,

	N: 78,

	O: 79,

	P: 80,

	Q: 81,

	R: 82,

	S: 83,

	T: 84,

	U: 85,

	V: 86,

	W: 87,

	X: 88,

	Y: 89,

	Z: 90,

	CONTEXT_MENU: 93,

	NUM_ZERO: 96,

	NUM_ONE: 97,

	NUM_TWO: 98,

	NUM_THREE: 99,

	NUM_FOUR: 100,

	NUM_FIVE: 101,

	NUM_SIX: 102,

	NUM_SEVEN: 103,

	NUM_EIGHT: 104,

	NUM_NINE: 105,

	NUM_MULTIPLY: 106,

	NUM_PLUS: 107,

	NUM_MINUS: 109,

	NUM_PERIOD: 110,

	NUM_DIVISION: 111,

	F1: 112,

	F2: 113,

	F3: 114,

	F4: 115,

	F5: 116,

	F6: 117,

	F7: 118,

	F8: 119,

	F9: 120,

	F10: 121,

	F11: 122,

	F12: 123,


	isNavKeyPress : function(){
		var me = this,
		k = this.normalizeKey(me.keyCode);
		return (k >= 33 && k <= 40) ||
		k == me.RETURN ||
		k == me.TAB ||
		k == me.ESC;
	},

	isSpecialKey : function(){
		var k = this.normalizeKey(this.keyCode);
		return (this.type == 'keypress' && this.ctrlKey) ||
		this.isNavKeyPress() ||
		(k == this.BACKSPACE) ||
		(k >= 16 && k <= 20) ||
		(k >= 44 && k <= 46);
	},

	getPoint : function(){
		return new Ext.lib.Point(this.xy[0], this.xy[1]);
	},


	hasModifier : function(){
		return ((this.ctrlKey || this.altKey) || this.shiftKey);
	}
});
Ext.Element.addMethods({

	swallowEvent : function(eventName, preventDefault) {
		var me = this;
		function fn(e) {
			e.stopPropagation();
			if (preventDefault) {
				e.preventDefault();
			}
		}

		if (Ext.isArray(eventName)) {
			Ext.each(eventName, function(e) {
				me.on(e, fn);
			});
			return me;
		}
		me.on(eventName, fn);
		return me;
	},


	relayEvent : function(eventName, observable) {
		this.on(eventName, function(e) {
			observable.fireEvent(eventName, e);
		});
	},


	clean : function(forceReclean) {
		var me  = this,
		dom = me.dom,
		n   = dom.firstChild,
		ni  = -1;

		if (Ext.Element.data(dom, 'isCleaned') && forceReclean !== true) {
			return me;
		}

		while (n) {
			var nx = n.nextSibling;
			if (n.nodeType == 3 && !(/\S/.test(n.nodeValue))) {
				dom.removeChild(n);
			} else {
				n.nodeIndex = ++ni;
			}
			n = nx;
		}

		Ext.Element.data(dom, 'isCleaned', true);
		return me;
	},


	load : function() {
		var updateManager = this.getUpdater();
		updateManager.update.apply(updateManager, arguments);

		return this;
	},


	getUpdater : function() {
		return this.updateManager || (this.updateManager = new Ext.Updater(this));
	},


	update : function(html, loadScripts, callback) {
		if (!this.dom) {
			return this;
		}
		html = html || "";

		if (loadScripts !== true) {
			this.dom.innerHTML = html;
			if (typeof callback == 'function') {
				callback();
			}
			return this;
		}

		var id  = Ext.id(),
		dom = this.dom;

		html += '<span id="' + id + '"></span>';

		Ext.lib.Event.onAvailable(id, function() {
			var DOC    = document,
			hd     = DOC.getElementsByTagName("head")[0],
			re     = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig,
			srcRe  = /\ssrc=([\'\"])(.*?)\1/i,
			typeRe = /\stype=([\'\"])(.*?)\1/i,
			match,
			attrs,
			srcMatch,
			typeMatch,
			el,
			s;

			while ((match = re.exec(html))) {
				attrs = match[1];
				srcMatch = attrs ? attrs.match(srcRe) : false;
				if (srcMatch && srcMatch[2]) {
					s = DOC.createElement("script");
					s.src = srcMatch[2];
					typeMatch = attrs.match(typeRe);
					if (typeMatch && typeMatch[2]) {
						s.type = typeMatch[2];
					}
					hd.appendChild(s);
				} else if (match[2] && match[2].length > 0) {
					if (window.execScript) {
						window.execScript(match[2]);
					} else {
						window.eval(match[2]);
					}
				}
			}

			el = DOC.getElementById(id);
			if (el) {
				Ext.removeNode(el);
			}

			if (typeof callback == 'function') {
				callback();
			}
		});
		dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig, "");
		return this;
	},


	removeAllListeners : function() {
		this.removeAnchor();
		Ext.EventManager.removeAll(this.dom);
		return this;
	},


	createProxy : function(config, renderTo, matchBox) {
		config = (typeof config == 'object') ? config : {
			tag : "div",
			cls: config
		};

		var me = this,
		proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) :
		Ext.DomHelper.insertBefore(me.dom, config, true);

		if (matchBox && me.setBox && me.getBox) {
			proxy.setBox(me.getBox());
		}
		return proxy;
	}
});

Ext.Element.prototype.getUpdateManager = Ext.Element.prototype.getUpdater;

Ext.Element.addMethods({

	getAnchorXY : function(anchor, local, s){


		anchor = (anchor || "tl").toLowerCase();
		s = s || {};

		var me = this,
		vp = me.dom == document.body || me.dom == document,
		w = s.width || vp ? Ext.lib.Dom.getViewWidth() : me.getWidth(),
		h = s.height || vp ? Ext.lib.Dom.getViewHeight() : me.getHeight(),
		xy,
		r = Math.round,
		o = me.getXY(),
		scroll = me.getScroll(),
		extraX = vp ? scroll.left : !local ? o[0] : 0,
		extraY = vp ? scroll.top : !local ? o[1] : 0,
		hash = {
			c  : [r(w * 0.5), r(h * 0.5)],
			t  : [r(w * 0.5), 0],
			l  : [0, r(h * 0.5)],
			r  : [w, r(h * 0.5)],
			b  : [r(w * 0.5), h],
			tl : [0, 0],
			bl : [0, h],
			br : [w, h],
			tr : [w, 0]
		};

		xy = hash[anchor];
		return [xy[0] + extraX, xy[1] + extraY];
	},


	anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){
		var me = this,
		dom = me.dom,
		scroll = !Ext.isEmpty(monitorScroll),
		action = function(){
			Ext.fly(dom).alignTo(el, alignment, offsets, animate);
			Ext.callback(callback, Ext.fly(dom));
		},
		anchor = this.getAnchor();


		this.removeAnchor();
		Ext.apply(anchor, {
			fn: action,
			scroll: scroll
		});

		Ext.EventManager.onWindowResize(action, null);

		if(scroll){
			Ext.EventManager.on(window, 'scroll', action, null,
			{
				buffer: !isNaN(monitorScroll) ? monitorScroll : 50
				});
		}
		action.call(me);
		return me;
	},


	removeAnchor : function(){
		var me = this,
		anchor = this.getAnchor();

		if(anchor && anchor.fn){
			Ext.EventManager.removeResizeListener(anchor.fn);
			if(anchor.scroll){
				Ext.EventManager.un(window, 'scroll', anchor.fn);
			}
			delete anchor.fn;
		}
		return me;
	},


	getAnchor : function(){
		var data = Ext.Element.data,
		dom = this.dom;
		if (!dom) {
			return;
		}
		var anchor = data(dom, '_anchor');

		if(!anchor){
			anchor = data(dom, '_anchor', {});
		}
		return anchor;
	},


	getAlignToXY : function(el, p, o){
		el = Ext.get(el);

		if(!el || !el.dom){
			throw "Element.alignToXY with an element that doesn't exist";
		}

		o = o || [0,0];
		p = (!p || p == "?" ? "tl-bl?" : (!(/-/).test(p) && p !== "" ? "tl-" + p : p || "tl-bl")).toLowerCase();

		var me = this,
		d = me.dom,
		a1,
		a2,
		x,
		y,

		w,
		h,
		r,
		dw = Ext.lib.Dom.getViewWidth() -10,
		dh = Ext.lib.Dom.getViewHeight()-10,
		p1y,
		p1x,
		p2y,
		p2x,
		swapY,
		swapX,
		doc = document,
		docElement = doc.documentElement,
		docBody = doc.body,
		scrollX = (docElement.scrollLeft || docBody.scrollLeft || 0)+5,
		scrollY = (docElement.scrollTop || docBody.scrollTop || 0)+5,
		c = false,
		p1 = "",
		p2 = "",
		m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/);

		if(!m){
			throw "Element.alignTo with an invalid alignment " + p;
		}

		p1 = m[1];
		p2 = m[2];
		c = !!m[3];



		a1 = me.getAnchorXY(p1, true);
		a2 = el.getAnchorXY(p2, false);

		x = a2[0] - a1[0] + o[0];
		y = a2[1] - a1[1] + o[1];

		if(c){
			w = me.getWidth();
			h = me.getHeight();
			r = el.getRegion();



			p1y = p1.charAt(0);
			p1x = p1.charAt(p1.length-1);
			p2y = p2.charAt(0);
			p2x = p2.charAt(p2.length-1);
			swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));
			swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));


			if (x + w > dw + scrollX) {
				x = swapX ? r.left-w : dw+scrollX-w;
			}
			if (x < scrollX) {
				x = swapX ? r.right : scrollX;
			}
			if (y + h > dh + scrollY) {
				y = swapY ? r.top-h : dh+scrollY-h;
			}
			if (y < scrollY){
				y = swapY ? r.bottom : scrollY;
			}
		}
		return [x,y];
	},


	alignTo : function(element, position, offsets, animate){
		var me = this;
		return me.setXY(me.getAlignToXY(element, position, offsets),
			me.preanim && !!animate ? me.preanim(arguments, 3) : false);
	},


	adjustForConstraints : function(xy, parent, offsets){
		return this.getConstrainToXY(parent || document, false, offsets, xy) ||  xy;
	},


	getConstrainToXY : function(el, local, offsets, proposedXY){
		var os = {
			top:0,
			left:0,
			bottom:0,
			right: 0
		};

		return function(el, local, offsets, proposedXY){
			el = Ext.get(el);
			offsets = offsets ? Ext.applyIf(offsets, os) : os;

			var vw, vh, vx = 0, vy = 0;
			if(el.dom == document.body || el.dom == document){
				vw =Ext.lib.Dom.getViewWidth();
				vh = Ext.lib.Dom.getViewHeight();
			}else{
				vw = el.dom.clientWidth;
				vh = el.dom.clientHeight;
				if(!local){
					var vxy = el.getXY();
					vx = vxy[0];
					vy = vxy[1];
				}
			}

			var s = el.getScroll();

			vx += offsets.left + s.left;
			vy += offsets.top + s.top;

			vw -= offsets.right;
			vh -= offsets.bottom;

			var vr = vx + vw,
			vb = vy + vh,
			xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]),
			x = xy[0], y = xy[1],
			offset = this.getConstrainOffset(),
			w = this.dom.offsetWidth + offset,
			h = this.dom.offsetHeight + offset;


			var moved = false;


			if((x + w) > vr){
				x = vr - w;
				moved = true;
			}
			if((y + h) > vb){
				y = vb - h;
				moved = true;
			}

			if(x < vx){
				x = vx;
				moved = true;
			}
			if(y < vy){
				y = vy;
				moved = true;
			}
			return moved ? [x, y] : false;
		};
	}(),

























































	getConstrainOffset : function(){
		return 0;
	},


	getCenterXY : function(){
		return this.getAlignToXY(document, 'c-c');
	},


	center : function(centerIn){
		return this.alignTo(centerIn || document, 'c-c');
	}
});

Ext.Element.addMethods({

	select : function(selector, unique){
		return Ext.Element.select(selector, unique, this.dom);
	}
});
Ext.apply(Ext.Element.prototype, function() {
	var GETDOM = Ext.getDom,
	GET = Ext.get,
	DH = Ext.DomHelper;

	return {

		insertSibling: function(el, where, returnDom){
			var me = this,
			rt,
			isAfter = (where || 'before').toLowerCase() == 'after',
			insertEl;

			if(Ext.isArray(el)){
				insertEl = me;
				Ext.each(el, function(e) {
					rt = Ext.fly(insertEl, '_internal').insertSibling(e, where, returnDom);
					if(isAfter){
						insertEl = rt;
					}
				});
				return rt;
			}

			el = el || {};

			if(el.nodeType || el.dom){
				rt = me.dom.parentNode.insertBefore(GETDOM(el), isAfter ? me.dom.nextSibling : me.dom);
				if (!returnDom) {
					rt = GET(rt);
				}
			}else{
				if (isAfter && !me.dom.nextSibling) {
					rt = DH.append(me.dom.parentNode, el, !returnDom);
				} else {
					rt = DH[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom);
				}
			}
			return rt;
		}
	};
}());


Ext.Element.boxMarkup = '<div class="{0}-tl"><div class="{0}-tr"><div class="{0}-tc"></div></div></div><div class="{0}-ml"><div class="{0}-mr"><div class="{0}-mc"></div></div></div><div class="{0}-bl"><div class="{0}-br"><div class="{0}-bc"></div></div></div>';

Ext.Element.addMethods(function(){
	var INTERNAL = "_internal",
	pxMatch = /(\d+\.?\d+)px/;
	return {

		applyStyles : function(style){
			Ext.DomHelper.applyStyles(this.dom, style);
			return this;
		},


		getStyles : function(){
			var ret = {};
			Ext.each(arguments, function(v) {
				ret[v] = this.getStyle(v);
			},
			this);
			return ret;
		},


		setOverflow : function(v){
			var dom = this.dom;
			if(v=='auto' && Ext.isMac && Ext.isGecko2){
				dom.style.overflow = 'hidden';
				(function(){
					dom.style.overflow = 'auto';
				}).defer(1);
			}else{
				dom.style.overflow = v;
			}
		},


		boxWrap : function(cls){
			cls = cls || 'x-box';
			var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + String.format(Ext.Element.boxMarkup, cls) + "</div>"));
			Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);
			return el;
		},


		setSize : function(width, height, animate){
			var me = this;
			if(typeof width == 'object'){
				height = width.height;
				width = width.width;
			}
			width = me.adjustWidth(width);
			height = me.adjustHeight(height);
			if(!animate || !me.anim){
				me.dom.style.width = me.addUnits(width);
				me.dom.style.height = me.addUnits(height);
			}else{
				me.anim({
					width: {
						to: width
					},
					height: {
						to: height
					}
				}, me.preanim(arguments, 2));
		}
		return me;
	},


	getComputedHeight : function(){
		var me = this,
		h = Math.max(me.dom.offsetHeight, me.dom.clientHeight);
		if(!h){
			h = parseFloat(me.getStyle('height')) || 0;
			if(!me.isBorderBox()){
				h += me.getFrameWidth('tb');
			}
		}
		return h;
	},


	getComputedWidth : function(){
		var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth);
		if(!w){
			w = parseFloat(this.getStyle('width')) || 0;
			if(!this.isBorderBox()){
				w += this.getFrameWidth('lr');
			}
		}
		return w;
	},


	getFrameWidth : function(sides, onlyContentBox){
		return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
	},


	addClassOnOver : function(className){
		this.hover(
			function(){
				Ext.fly(this, INTERNAL).addClass(className);
			},
			function(){
				Ext.fly(this, INTERNAL).removeClass(className);
			}
			);
		return this;
	},


	addClassOnFocus : function(className){
		this.on("focus", function(){
			Ext.fly(this, INTERNAL).addClass(className);
		}, this.dom);
		this.on("blur", function(){
			Ext.fly(this, INTERNAL).removeClass(className);
		}, this.dom);
		return this;
	},


	addClassOnClick : function(className){
		var dom = this.dom;
		this.on("mousedown", function(){
			Ext.fly(dom, INTERNAL).addClass(className);
			var d = Ext.getDoc(),
			fn = function(){
				Ext.fly(dom, INTERNAL).removeClass(className);
				d.removeListener("mouseup", fn);
			};
			d.on("mouseup", fn);
		});
		return this;
	},



	getViewSize : function(){
		var doc = document,
		d = this.dom,
		isDoc = (d == doc || d == doc.body);


		if (isDoc) {
			var extdom = Ext.lib.Dom;
			return {
				width : extdom.getViewWidth(),
				height : extdom.getViewHeight()
			};


		} else {
			return {
				width : d.clientWidth,
				height : d.clientHeight
			};
		}
	},



	getStyleSize : function(){
		var me = this,
		w, h,
		doc = document,
		d = this.dom,
		isDoc = (d == doc || d == doc.body),
		s = d.style;


		if (isDoc) {
			var extdom = Ext.lib.Dom;
			return {
				width : extdom.getViewWidth(),
				height : extdom.getViewHeight()
			};
		}

		if(s.width && s.width != 'auto'){
			w = parseFloat(s.width);
			if(me.isBorderBox()){
				w -= me.getFrameWidth('lr');
			}
		}

		if(s.height && s.height != 'auto'){
			h = parseFloat(s.height);
			if(me.isBorderBox()){
				h -= me.getFrameWidth('tb');
			}
		}

		return {
			width: w || me.getWidth(true),
			height: h || me.getHeight(true)
			};
	},


	getSize : function(contentSize){
		return {
			width: this.getWidth(contentSize),
			height: this.getHeight(contentSize)
			};
	},


	repaint : function(){
		var dom = this.dom;
		this.addClass("x-repaint");
		setTimeout(function(){
			Ext.fly(dom).removeClass("x-repaint");
		}, 1);
		return this;
	},


	unselectable : function(){
		this.dom.unselectable = "on";
		return this.swallowEvent("selectstart", true).
		applyStyles("-moz-user-select:none;-khtml-user-select:none;").
		addClass("x-unselectable");
	},


	getMargins : function(side){
		var me = this,
		key,
		hash = {
			t:"top",
			l:"left",
			r:"right",
			b: "bottom"
		},
		o = {};

		if (!side) {
			for (key in me.margins){
				o[hash[key]] = parseFloat(me.getStyle(me.margins[key])) || 0;
			}
			return o;
		} else {
			return me.addStyles.call(me, side, me.margins);
		}
	}
};
}());

Ext.Element.addMethods({

	setBox : function(box, adjust, animate){
		var me = this,
		w = box.width,
		h = box.height;
		if((adjust && !me.autoBoxAdjust) && !me.isBorderBox()){
			w -= (me.getBorderWidth("lr") + me.getPadding("lr"));
			h -= (me.getBorderWidth("tb") + me.getPadding("tb"));
		}
		me.setBounds(box.x, box.y, w, h, me.animTest.call(me, arguments, animate, 2));
		return me;
	},


	getBox : function(contentBox, local) {
		var me = this,
		xy,
		left,
		top,
		getBorderWidth = me.getBorderWidth,
		getPadding = me.getPadding,
		l,
		r,
		t,
		b;
		if(!local){
			xy = me.getXY();
		}else{
			left = parseInt(me.getStyle("left"), 10) || 0;
			top = parseInt(me.getStyle("top"), 10) || 0;
			xy = [left, top];
		}
		var el = me.dom, w = el.offsetWidth, h = el.offsetHeight, bx;
		if(!contentBox){
			bx = {
				x: xy[0],
				y: xy[1],
				0: xy[0],
				1: xy[1],
				width: w,
				height: h
			};
		}else{
			l = getBorderWidth.call(me, "l") + getPadding.call(me, "l");
			r = getBorderWidth.call(me, "r") + getPadding.call(me, "r");
			t = getBorderWidth.call(me, "t") + getPadding.call(me, "t");
			b = getBorderWidth.call(me, "b") + getPadding.call(me, "b");
			bx = {
				x: xy[0]+l,
				y: xy[1]+t,
				0: xy[0]+l,
				1: xy[1]+t,
				width: w-(l+r),
				height: h-(t+b)
				};
		}
		bx.right = bx.x + bx.width;
		bx.bottom = bx.y + bx.height;
		return bx;
	},


	move : function(direction, distance, animate){
		var me = this,
		xy = me.getXY(),
		x = xy[0],
		y = xy[1],
		left = [x - distance, y],
		right = [x + distance, y],
		top = [x, y - distance],
		bottom = [x, y + distance],
		hash = {
			l :	left,
			left : left,
			r : right,
			right : right,
			t : top,
			top : top,
			up : top,
			b : bottom,
			bottom : bottom,
			down : bottom
		};

		direction = direction.toLowerCase();
		me.moveTo(hash[direction][0], hash[direction][1], me.animTest.call(me, arguments, animate, 2));
	},


	setLeftTop : function(left, top){
		var me = this,
		style = me.dom.style;
		style.left = me.addUnits(left);
		style.top = me.addUnits(top);
		return me;
	},


	getRegion : function(){
		return Ext.lib.Dom.getRegion(this.dom);
	},


	setBounds : function(x, y, width, height, animate){
		var me = this;
		if (!animate || !me.anim) {
			me.setSize(width, height);
			me.setLocation(x, y);
		} else {
			me.anim({
				points: {
					to: [x, y]
					},
				width: {
					to: me.adjustWidth(width)
					},
				height: {
					to: me.adjustHeight(height)
					}
				},
			me.preanim(arguments, 4),
			'motion');
	}
	return me;
},


setRegion : function(region, animate) {
	return this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, this.animTest.call(this, arguments, animate, 1));
}
});
Ext.Element.addMethods({

	scrollTo : function(side, value, animate) {

		var top = /top/i.test(side),
		me = this,
		dom = me.dom,
		prop;
		if (!animate || !me.anim) {

			prop = 'scroll' + (top ? 'Top' : 'Left');
			dom[prop] = value;
		}
		else {

			prop = 'scroll' + (top ? 'Left' : 'Top');
			me.anim({
				scroll: {
					to: top ? [dom[prop], value] : [value, dom[prop]]
					}
				}, me.preanim(arguments, 2), 'scroll');
	}
	return me;
},


scrollIntoView : function(container, hscroll) {
	var c = Ext.getDom(container) || Ext.getBody().dom,
	el = this.dom,
	o = this.getOffsetsTo(c),
	l = o[0] + c.scrollLeft,
	t = o[1] + c.scrollTop,
	b = t + el.offsetHeight,
	r = l + el.offsetWidth,
	ch = c.clientHeight,
	ct = parseInt(c.scrollTop, 10),
	cl = parseInt(c.scrollLeft, 10),
	cb = ct + ch,
	cr = cl + c.clientWidth;

	if (el.offsetHeight > ch || t < ct) {
		c.scrollTop = t;
	}
	else if (b > cb) {
		c.scrollTop = b-ch;
	}

	c.scrollTop = c.scrollTop;

	if (hscroll !== false) {
		if (el.offsetWidth > c.clientWidth || l < cl) {
			c.scrollLeft = l;
		}
		else if (r > cr) {
			c.scrollLeft = r - c.clientWidth;
		}
		c.scrollLeft = c.scrollLeft;
	}
	return this;
},


scrollChildIntoView : function(child, hscroll) {
	Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll);
},


scroll : function(direction, distance, animate) {
	if (!this.isScrollable()) {
		return false;
	}
	var el = this.dom,
	l = el.scrollLeft, t = el.scrollTop,
	w = el.scrollWidth, h = el.scrollHeight,
	cw = el.clientWidth, ch = el.clientHeight,
	scrolled = false, v,
	hash = {
		l: Math.min(l + distance, w-cw),
		r: v = Math.max(l - distance, 0),
		t: Math.max(t - distance, 0),
		b: Math.min(t + distance, h-ch)
	};
	hash.d = hash.b;
	hash.u = hash.t;

	direction = direction.substr(0, 1);
	if ((v = hash[direction]) > -1) {
		scrolled = true;
		this.scrollTo(direction == 'l' || direction == 'r' ? 'left' : 'top', v, this.preanim(arguments, 2));
	}
	return scrolled;
}
});
Ext.Element.addMethods(
	function() {
		var VISIBILITY      = "visibility",
		DISPLAY         = "display",
		HIDDEN          = "hidden",
		NONE            = "none",
		XMASKED         = "x-masked",
		XMASKEDRELATIVE = "x-masked-relative",
		data            = Ext.Element.data;

		return {

			isVisible : function(deep) {
				var vis = !this.isStyle(VISIBILITY, HIDDEN) && !this.isStyle(DISPLAY, NONE),
				p   = this.dom.parentNode;

				if (deep !== true || !vis) {
					return vis;
				}

				while (p && !(/^body/i.test(p.tagName))) {
					if (!Ext.fly(p, '_isVisible').isVisible()) {
						return false;
					}
					p = p.parentNode;
				}
				return true;
			},


			isDisplayed : function() {
				return !this.isStyle(DISPLAY, NONE);
			},


			enableDisplayMode : function(display) {
				this.setVisibilityMode(Ext.Element.DISPLAY);

				if (!Ext.isEmpty(display)) {
					data(this.dom, 'originalDisplay', display);
				}

				return this;
			},


			mask : function(msg, msgCls) {
				var me  = this,
				dom = me.dom,
				dh  = Ext.DomHelper,
				EXTELMASKMSG = "ext-el-mask-msg",
				el,
				mask;

				if (!(/^body/i.test(dom.tagName) && me.getStyle('position') == 'static')) {
					me.addClass(XMASKEDRELATIVE);
				}
				if (el = data(dom, 'maskMsg')) {
					el.remove();
				}
				if (el = data(dom, 'mask')) {
					el.remove();
				}

				mask = dh.append(dom, {
					cls : "ext-el-mask"
				}, true);
				data(dom, 'mask', mask);

				me.addClass(XMASKED);
				mask.setDisplayed(true);

				if (typeof msg == 'string') {
					var mm = dh.append(dom, {
						cls : EXTELMASKMSG,
						cn:{
							tag:'div'
						}
					}, true);
				data(dom, 'maskMsg', mm);
				mm.dom.className = msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG;
				mm.dom.firstChild.innerHTML = msg;
				mm.setDisplayed(true);
				mm.center(me);
			}


			if (Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && me.getStyle('height') == 'auto') {
				mask.setSize(undefined, me.getHeight());
			}

			return mask;
		},


		unmask : function() {
			var me      = this,
			dom     = me.dom,
			mask    = data(dom, 'mask'),
			maskMsg = data(dom, 'maskMsg');

			if (mask) {
				if (maskMsg) {
					maskMsg.remove();
					data(dom, 'maskMsg', undefined);
				}

				mask.remove();
				data(dom, 'mask', undefined);
				me.removeClass([XMASKED, XMASKEDRELATIVE]);
			}
		},


		isMasked : function() {
			var m = data(this.dom, 'mask');
			return m && m.isVisible();
		},


		createShim : function() {
			var el = document.createElement('iframe'),
			shim;

			el.frameBorder = '0';
			el.className = 'ext-shim';
			el.src = Ext.SSL_SECURE_URL;
			shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom));
			shim.autoBoxAdjust = false;
			return shim;
		}
	};
}()
	);
Ext.Element.addMethods({

	addKeyListener : function(key, fn, scope){
		var config;
		if(typeof key != 'object' || Ext.isArray(key)){
			config = {
				key: key,
				fn: fn,
				scope: scope
			};
		}else{
			config = {
				key : key.key,
				shift : key.shift,
				ctrl : key.ctrl,
				alt : key.alt,
				fn: fn,
				scope: scope
			};
		}
		return new Ext.KeyMap(this, config);
	},


	addKeyMap : function(config){
		return new Ext.KeyMap(this, config);
	}
});



Ext.CompositeElementLite.importElementMethods();
Ext.apply(Ext.CompositeElementLite.prototype, {
	addElements : function(els, root){
		if(!els){
			return this;
		}
		if(typeof els == "string"){
			els = Ext.Element.selectorFunction(els, root);
		}
		var yels = this.elements;
		Ext.each(els, function(e) {
			yels.push(Ext.get(e));
		});
		return this;
	},


	first : function(){
		return this.item(0);
	},


	last : function(){
		return this.item(this.getCount()-1);
	},


	contains : function(el){
		return this.indexOf(el) != -1;
	},


	removeElement : function(keys, removeDom){
		var me = this,
		els = this.elements,
		el;
		Ext.each(keys, function(val){
			if ((el = (els[val] || els[val = me.indexOf(val)]))) {
				if(removeDom){
					if(el.dom){
						el.remove();
					}else{
						Ext.removeNode(el);
					}
				}
				els.splice(val, 1);
			}
		});
		return this;
	}
});

Ext.CompositeElement = Ext.extend(Ext.CompositeElementLite, {

	constructor : function(els, root){
		this.elements = [];
		this.add(els, root);
	},


	getElement : function(el){

		return el;
	},


	transformElement : function(el){
		return Ext.get(el);
	}






});


Ext.Element.select = function(selector, unique, root){
	var els;
	if(typeof selector == "string"){
		els = Ext.Element.selectorFunction(selector, root);
	}else if(selector.length !== undefined){
		els = selector;
	}else{
		throw "Invalid selector";
	}

	return (unique === true) ? new Ext.CompositeElement(els) : new Ext.CompositeElementLite(els);
};


Ext.select = Ext.Element.select;
Ext.UpdateManager = Ext.Updater = Ext.extend(Ext.util.Observable,
	function() {
		var BEFOREUPDATE = "beforeupdate",
		UPDATE = "update",
		FAILURE = "failure";


		function processSuccess(response){
			var me = this;
			me.transaction = null;
			if (response.argument.form && response.argument.reset) {
				try {
					response.argument.form.reset();
				} catch(e){}
			}
			if (me.loadScripts) {
				me.renderer.render(me.el, response, me,
					updateComplete.createDelegate(me, [response]));
			} else {
				me.renderer.render(me.el, response, me);
				updateComplete.call(me, response);
			}
		}


		function updateComplete(response, type, success){
			this.fireEvent(type || UPDATE, this.el, response);
			if(Ext.isFunction(response.argument.callback)){
				response.argument.callback.call(response.argument.scope, this.el, Ext.isEmpty(success) ? true : false, response, response.argument.options);
			}
		}


		function processFailure(response){
			updateComplete.call(this, response, FAILURE, !!(this.transaction = null));
		}

		return {
			constructor: function(el, forceNew){
				var me = this;
				el = Ext.get(el);
				if(!forceNew && el.updateManager){
					return el.updateManager;
				}

				me.el = el;

				me.defaultUrl = null;

				me.addEvents(

					BEFOREUPDATE,

					UPDATE,

					FAILURE
					);

				Ext.apply(me, Ext.Updater.defaults);








				me.transaction = null;

				me.refreshDelegate = me.refresh.createDelegate(me);

				me.updateDelegate = me.update.createDelegate(me);

				me.formUpdateDelegate = (me.formUpdate || function(){}).createDelegate(me);


				me.renderer = me.renderer || me.getDefaultRenderer();

				Ext.Updater.superclass.constructor.call(me);
			},


			setRenderer : function(renderer){
				this.renderer = renderer;
			},


			getRenderer : function(){
				return this.renderer;
			},


			getDefaultRenderer: function() {
				return new Ext.Updater.BasicRenderer();
			},


			setDefaultUrl : function(defaultUrl){
				this.defaultUrl = defaultUrl;
			},


			getEl : function(){
				return this.el;
			},


			update : function(url, params, callback, discardUrl){
				var me = this,
				cfg,
				callerScope;

				if(me.fireEvent(BEFOREUPDATE, me.el, url, params) !== false){
					if(Ext.isObject(url)){
						cfg = url;
						url = cfg.url;
						params = params || cfg.params;
						callback = callback || cfg.callback;
						discardUrl = discardUrl || cfg.discardUrl;
						callerScope = cfg.scope;
						if(!Ext.isEmpty(cfg.nocache)){
							me.disableCaching = cfg.nocache;
						};
						if(!Ext.isEmpty(cfg.text)){
							me.indicatorText = '<div class="loading-indicator">'+cfg.text+"</div>";
						};
						if(!Ext.isEmpty(cfg.scripts)){
							me.loadScripts = cfg.scripts;
						};
						if(!Ext.isEmpty(cfg.timeout)){
							me.timeout = cfg.timeout;
						};
					}
					me.showLoading();

					if(!discardUrl){
						me.defaultUrl = url;
					}
					if(Ext.isFunction(url)){
						url = url.call(me);
					}

					var o = Ext.apply({}, {
						url : url,
						params: (Ext.isFunction(params) && callerScope) ? params.createDelegate(callerScope) : params,
						success: processSuccess,
						failure: processFailure,
						scope: me,
						callback: undefined,
						timeout: (me.timeout*1000),
						disableCaching: me.disableCaching,
						argument: {
							"options": cfg,
							"url": url,
							"form": null,
							"callback": callback,
							"scope": callerScope || window,
							"params": params
						}
					}, cfg);

					me.transaction = Ext.Ajax.request(o);
				}
			},


			formUpdate : function(form, url, reset, callback){
				var me = this;
				if(me.fireEvent(BEFOREUPDATE, me.el, form, url) !== false){
					if(Ext.isFunction(url)){
						url = url.call(me);
					}
					form = Ext.getDom(form);
					me.transaction = Ext.Ajax.request({
						form: form,
						url:url,
						success: processSuccess,
						failure: processFailure,
						scope: me,
						timeout: (me.timeout*1000),
						argument: {
							"url": url,
							"form": form,
							"callback": callback,
							"reset": reset
						}
					});
					me.showLoading.defer(1, me);
				}
			},


			startAutoRefresh : function(interval, url, params, callback, refreshNow){
				var me = this;
				if(refreshNow){
					me.update(url || me.defaultUrl, params, callback, true);
				}
				if(me.autoRefreshProcId){
					clearInterval(me.autoRefreshProcId);
				}
				me.autoRefreshProcId = setInterval(me.update.createDelegate(me, [url || me.defaultUrl, params, callback, true]), interval * 1000);
			},


			stopAutoRefresh : function(){
				if(this.autoRefreshProcId){
					clearInterval(this.autoRefreshProcId);
					delete this.autoRefreshProcId;
				}
			},


			isAutoRefreshing : function(){
				return !!this.autoRefreshProcId;
			},


			showLoading : function(){
				if(this.showLoadIndicator){
					this.el.dom.innerHTML = this.indicatorText;
				}
			},


			abort : function(){
				if(this.transaction){
					Ext.Ajax.abort(this.transaction);
				}
			},


			isUpdating : function(){
				return this.transaction ? Ext.Ajax.isLoading(this.transaction) : false;
			},


			refresh : function(callback){
				if(this.defaultUrl){
					this.update(this.defaultUrl, null, callback, true);
				}
			}
		};
	}());


Ext.Updater.defaults = {

	timeout : 30,

	disableCaching : false,

	showLoadIndicator : true,

	indicatorText : '<div class="loading-indicator">Loading...</div>',

	loadScripts : false,

	sslBlankUrl : Ext.SSL_SECURE_URL
};



Ext.Updater.updateElement = function(el, url, params, options){
	var um = Ext.get(el).getUpdater();
	Ext.apply(um, options);
	um.update(url, params, options ? options.callback : null);
};


Ext.Updater.BasicRenderer = function(){};

Ext.Updater.BasicRenderer.prototype = {

	render : function(el, response, updateManager, callback){
		el.update(response.responseText, updateManager.loadScripts, callback);
	}
};



(function() {


	Date.useStrict = false;





	function xf(format) {
		var args = Array.prototype.slice.call(arguments, 1);
		return format.replace(/\{(\d+)\}/g, function(m, i) {
			return args[i];
		});
	}



	Date.formatCodeToRegex = function(character, currentGroup) {

		var p = Date.parseCodes[character];

		if (p) {
			p = typeof p == 'function'? p() : p;
			Date.parseCodes[character] = p;
		}

		return p ? Ext.applyIf({
			c: p.c ? xf(p.c, currentGroup || "{0}") : p.c
		}, p) : {
			g:0,
			c:null,
			s:Ext.escapeRe(character)
		};
	};


	var $f = Date.formatCodeToRegex;

	Ext.apply(Date, {

		parseFunctions: {
			"M$": function(input, strict) {


				var re = new RegExp('\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/');
				var r = (input || '').match(re);
				return r? new Date(((r[1] || '') + r[2]) * 1) : null;
			}
		},
		parseRegexes: [],


		formatFunctions: {
			"M$": function() {

				return '\\/Date(' + this.getTime() + ')\\/';
			}
		},

		y2kYear : 50,


		MILLI : "ms",


		SECOND : "s",


		MINUTE : "mi",


		HOUR : "h",


		DAY : "d",


		MONTH : "mo",


		YEAR : "y",


		defaults: {},


		dayNames : [
		"Sunday",
		"Monday",
		"Tuesday",
		"Wednesday",
		"Thursday",
		"Friday",
		"Saturday"
		],


		monthNames : [
		"January",
		"February",
		"March",
		"April",
		"May",
		"June",
		"July",
		"August",
		"September",
		"October",
		"November",
		"December"
		],


		monthNumbers : {
			Jan:0,
			Feb:1,
			Mar:2,
			Apr:3,
			May:4,
			Jun:5,
			Jul:6,
			Aug:7,
			Sep:8,
			Oct:9,
			Nov:10,
			Dec:11
		},


		getShortMonthName : function(month) {
			return Date.monthNames[month].substring(0, 3);
		},


		getShortDayName : function(day) {
			return Date.dayNames[day].substring(0, 3);
		},


		getMonthNumber : function(name) {

			return Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];
		},


		formatCodes : {
			d: "String.leftPad(this.getDate(), 2, '0')",
			D: "Date.getShortDayName(this.getDay())",
			j: "this.getDate()",
			l: "Date.dayNames[this.getDay()]",
			N: "(this.getDay() ? this.getDay() : 7)",
			S: "this.getSuffix()",
			w: "this.getDay()",
			z: "this.getDayOfYear()",
			W: "String.leftPad(this.getWeekOfYear(), 2, '0')",
			F: "Date.monthNames[this.getMonth()]",
			m: "String.leftPad(this.getMonth() + 1, 2, '0')",
			M: "Date.getShortMonthName(this.getMonth())",
			n: "(this.getMonth() + 1)",
			t: "this.getDaysInMonth()",
			L: "(this.isLeapYear() ? 1 : 0)",
			o: "(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0)))",
			Y: "String.leftPad(this.getFullYear(), 4, '0')",
			y: "('' + this.getFullYear()).substring(2, 4)",
			a: "(this.getHours() < 12 ? 'am' : 'pm')",
			A: "(this.getHours() < 12 ? 'AM' : 'PM')",
			g: "((this.getHours() % 12) ? this.getHours() % 12 : 12)",
			G: "this.getHours()",
			h: "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')",
			H: "String.leftPad(this.getHours(), 2, '0')",
			i: "String.leftPad(this.getMinutes(), 2, '0')",
			s: "String.leftPad(this.getSeconds(), 2, '0')",
			u: "String.leftPad(this.getMilliseconds(), 3, '0')",
			O: "this.getGMTOffset()",
			P: "this.getGMTOffset(true)",
			T: "this.getTimezone()",
			Z: "(this.getTimezoneOffset() * -60)",

			c: function() {
				for (var c = "Y-m-dTH:i:sP", code = [], i = 0, l = c.length; i < l; ++i) {
					var e = c.charAt(i);
					code.push(e == "T" ? "'T'" : Date.getFormatCode(e));
				}
				return code.join(" + ");
			},


			U: "Math.round(this.getTime() / 1000)"
		},


		isValid : function(y, m, d, h, i, s, ms) {

			h = h || 0;
			i = i || 0;
			s = s || 0;
			ms = ms || 0;


			var dt = new Date(y < 100 ? 100 : y, m - 1, d, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);

			return y == dt.getFullYear() &&
			m == dt.getMonth() + 1 &&
			d == dt.getDate() &&
			h == dt.getHours() &&
			i == dt.getMinutes() &&
			s == dt.getSeconds() &&
			ms == dt.getMilliseconds();
		},


		parseDate : function(input, format, strict) {
			var p = Date.parseFunctions;
			if (p[format] == null) {
				Date.createParser(format);
			}
			return p[format](input, Ext.isDefined(strict) ? strict : Date.useStrict);
		},


		getFormatCode : function(character) {
			var f = Date.formatCodes[character];

			if (f) {
				f = typeof f == 'function'? f() : f;
				Date.formatCodes[character] = f;
			}


			return f || ("'" + String.escape(character) + "'");
		},


		createFormat : function(format) {
			var code = [],
			special = false,
			ch = '';

			for (var i = 0; i < format.length; ++i) {
				ch = format.charAt(i);
				if (!special && ch == "\\") {
					special = true;
				} else if (special) {
					special = false;
					code.push("'" + String.escape(ch) + "'");
				} else {
					code.push(Date.getFormatCode(ch));
				}
			}
			Date.formatFunctions[format] = new Function("return " + code.join('+'));
		},


		createParser : function() {
			var code = [
			"var dt, y, m, d, h, i, s, ms, o, z, zz, u, v,",
			"def = Date.defaults,",
			"results = String(input).match(Date.parseRegexes[{0}]);",

			"if(results){",
			"{1}",

			"if(u != null){",
			"v = new Date(u * 1000);",
			"}else{",



			"dt = (new Date()).clearTime();",


			"y = Ext.num(y, Ext.num(def.y, dt.getFullYear()));",
			"m = Ext.num(m, Ext.num(def.m - 1, dt.getMonth()));",
			"d = Ext.num(d, Ext.num(def.d, dt.getDate()));",


			"h  = Ext.num(h, Ext.num(def.h, dt.getHours()));",
			"i  = Ext.num(i, Ext.num(def.i, dt.getMinutes()));",
			"s  = Ext.num(s, Ext.num(def.s, dt.getSeconds()));",
			"ms = Ext.num(ms, Ext.num(def.ms, dt.getMilliseconds()));",

			"if(z >= 0 && y >= 0){",





			"v = new Date(y < 100 ? 100 : y, 0, 1, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);",


			"v = !strict? v : (strict === true && (z <= 364 || (v.isLeapYear() && z <= 365))? v.add(Date.DAY, z) : null);",
			"}else if(strict === true && !Date.isValid(y, m + 1, d, h, i, s, ms)){",
			"v = null;",
			"}else{",


			"v = new Date(y < 100 ? 100 : y, m, d, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);",
			"}",
			"}",
			"}",

			"if(v){",

			"if(zz != null){",

			"v = v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - zz);",
			"}else if(o){",

			"v = v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));",
			"}",
			"}",

			"return v;"
			].join('\n');

			return function(format) {
				var regexNum = Date.parseRegexes.length,
				currentGroup = 1,
				calc = [],
				regex = [],
				special = false,
				ch = "",
				i = 0,
				obj,
				last;

				for (; i < format.length; ++i) {
					ch = format.charAt(i);
					if (!special && ch == "\\") {
						special = true;
					} else if (special) {
						special = false;
						regex.push(String.escape(ch));
					} else {
						obj = $f(ch, currentGroup);
						currentGroup += obj.g;
						regex.push(obj.s);
						if (obj.g && obj.c) {
							if (obj.calcLast) {
								last = obj.c;
							} else {
								calc.push(obj.c);
							}
						}
					}
				}

				if (last) {
					calc.push(last);
				}

				Date.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", 'i');
				Date.parseFunctions[format] = new Function("input", "strict", xf(code, regexNum, calc.join('')));
			};
		}(),


		parseCodes : {

			d: {
				g:1,
				c:"d = parseInt(results[{0}], 10);\n",
				s:"(\\d{2})"
			},
			j: {
				g:1,
				c:"d = parseInt(results[{0}], 10);\n",
				s:"(\\d{1,2})"
			},
			D: function() {
				for (var a = [], i = 0; i < 7; a.push(Date.getShortDayName(i)), ++i);
				return {
					g:0,
					c:null,
					s:"(?:" + a.join("|") +")"
				};
			},
			l: function() {
				return {
					g:0,
					c:null,
					s:"(?:" + Date.dayNames.join("|") + ")"
				};
			},
			N: {
				g:0,
				c:null,
				s:"[1-7]"
			},
			S: {
				g:0,
				c:null,
				s:"(?:st|nd|rd|th)"
			},
			w: {
				g:0,
				c:null,
				s:"[0-6]"
			},
			z: {
				g:1,
				c:"z = parseInt(results[{0}], 10);\n",
				s:"(\\d{1,3})"
			},
			W: {
				g:0,
				c:null,
				s:"(?:\\d{2})"
			},
			F: function() {
				return {
					g:1,
					c:"m = parseInt(Date.getMonthNumber(results[{0}]), 10);\n",
					s:"(" + Date.monthNames.join("|") + ")"
				};
			},
			M: function() {
				for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i);
				return Ext.applyIf({
					s:"(" + a.join("|") + ")"
				}, $f("F"));
			},
			m: {
				g:1,
				c:"m = parseInt(results[{0}], 10) - 1;\n",
				s:"(\\d{2})"
			},
			n: {
				g:1,
				c:"m = parseInt(results[{0}], 10) - 1;\n",
				s:"(\\d{1,2})"
			},
			t: {
				g:0,
				c:null,
				s:"(?:\\d{2})"
			},
			L: {
				g:0,
				c:null,
				s:"(?:1|0)"
			},
			o: function() {
				return $f("Y");
			},
			Y: {
				g:1,
				c:"y = parseInt(results[{0}], 10);\n",
				s:"(\\d{4})"
			},
			y: {
				g:1,
				c:"var ty = parseInt(results[{0}], 10);\n"
				+ "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",
				s:"(\\d{1,2})"
			},

			a: function(){
				return $f("A");
			},
			A: {

				calcLast: true,
				g:1,
				c:"if (/(am)/i.test(results[{0}])) {\n"
				+ "if (!h || h == 12) { h = 0; }\n"
				+ "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
				s:"(AM|PM|am|pm)"
			},
			g: function() {
				return $f("G");
			},
			G: {
				g:1,
				c:"h = parseInt(results[{0}], 10);\n",
				s:"(\\d{1,2})"
			},
			h: function() {
				return $f("H");
			},
			H: {
				g:1,
				c:"h = parseInt(results[{0}], 10);\n",
				s:"(\\d{2})"
			},
			i: {
				g:1,
				c:"i = parseInt(results[{0}], 10);\n",
				s:"(\\d{2})"
			},
			s: {
				g:1,
				c:"s = parseInt(results[{0}], 10);\n",
				s:"(\\d{2})"
			},
			u: {
				g:1,
				c:"ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n",
				s:"(\\d+)"
			},
			O: {
				g:1,
				c:[
				"o = results[{0}];",
				"var sn = o.substring(0,1),",
				"hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),",
				"mn = o.substring(3,5) % 60;",
				"o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"
				].join("\n"),
				s: "([+\-]\\d{4})"
			},
			P: {
				g:1,
				c:[
				"o = results[{0}];",
				"var sn = o.substring(0,1),",
				"hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),",
				"mn = o.substring(4,6) % 60;",
				"o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"
				].join("\n"),
				s: "([+\-]\\d{2}:\\d{2})"
			},
			T: {
				g:0,
				c:null,
				s:"[A-Z]{1,4}"
			},
			Z: {
				g:1,
				c:"zz = results[{0}] * 1;\n"
				+ "zz = (-43200 <= zz && zz <= 50400)? zz : null;\n",
				s:"([+\-]?\\d{1,5})"
			},
			c: function() {
				var calc = [],
				arr = [
				$f("Y", 1),
				$f("m", 2),
				$f("d", 3),
				$f("h", 4),
				$f("i", 5),
				$f("s", 6),
				{
					c:"ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"
				},

				{
					c:[
					"if(results[8]) {",
					"if(results[8] == 'Z'){",
					"zz = 0;",
					"}else if (results[8].indexOf(':') > -1){",
					$f("P", 8).c,
					"}else{",
					$f("O", 8).c,
					"}",
					"}"
					].join('\n')
					}
				];

				for (var i = 0, l = arr.length; i < l; ++i) {
					calc.push(arr[i].c);
				}

				return {
					g:1,
					c:calc.join(""),
					s:[
					arr[0].s,
					"(?:", "-", arr[1].s,
					"(?:", "-", arr[2].s,
					"(?:",
					"(?:T| )?",
					arr[3].s, ":", arr[4].s,
					"(?::", arr[5].s, ")?",
					"(?:(?:\\.|,)(\\d+))?",
					"(Z|(?:[-+]\\d{2}(?::)?\\d{2}))?",
					")?",
					")?",
					")?"
					].join("")
				};
			},
			U: {
				g:1,
				c:"u = parseInt(results[{0}], 10);\n",
				s:"(-?\\d+)"
			}
		}
	});

}());

Ext.apply(Date.prototype, {

	dateFormat : function(format) {
		if (Date.formatFunctions[format] == null) {
			Date.createFormat(format);
		}
		return Date.formatFunctions[format].call(this);
	},


	getTimezone : function() {












		return this.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");
	},


	getGMTOffset : function(colon) {
		return (this.getTimezoneOffset() > 0 ? "-" : "+")
		+ String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset()) / 60), 2, "0")
		+ (colon ? ":" : "")
		+ String.leftPad(Math.abs(this.getTimezoneOffset() % 60), 2, "0");
	},


	getDayOfYear: function() {
		var num = 0,
		d = this.clone(),
		m = this.getMonth(),
		i;

		for (i = 0, d.setDate(1), d.setMonth(0); i < m; d.setMonth(++i)) {
			num += d.getDaysInMonth();
		}
		return num + this.getDate() - 1;
	},


	getWeekOfYear : function() {

		var ms1d = 864e5,
		ms7d = 7 * ms1d;

		return function() {
			var DC3 = Date.UTC(this.getFullYear(), this.getMonth(), this.getDate() + 3) / ms1d,
			AWN = Math.floor(DC3 / 7),
			Wyr = new Date(AWN * ms7d).getUTCFullYear();

			return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
		};
	}(),


	isLeapYear : function() {
		var year = this.getFullYear();
		return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
	},


	getFirstDayOfMonth : function() {
		var day = (this.getDay() - (this.getDate() - 1)) % 7;
		return (day < 0) ? (day + 7) : day;
	},


	getLastDayOfMonth : function() {
		return this.getLastDateOfMonth().getDay();
	},



	getFirstDateOfMonth : function() {
		return new Date(this.getFullYear(), this.getMonth(), 1);
	},


	getLastDateOfMonth : function() {
		return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth());
	},


	getDaysInMonth: function() {
		var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

		return function() {
			var m = this.getMonth();

			return m == 1 && this.isLeapYear() ? 29 : daysInMonth[m];
		};
	}(),


	getSuffix : function() {
		switch (this.getDate()) {
			case 1:
			case 21:
			case 31:
				return "st";
			case 2:
			case 22:
				return "nd";
			case 3:
			case 23:
				return "rd";
			default:
				return "th";
		}
	},


	clone : function() {
		return new Date(this.getTime());
	},


	isDST : function() {


		return new Date(this.getFullYear(), 0, 1).getTimezoneOffset() != this.getTimezoneOffset();
	},


	clearTime : function(clone) {
		if (clone) {
			return this.clone().clearTime();
		}


		var d = this.getDate();


		this.setHours(0);
		this.setMinutes(0);
		this.setSeconds(0);
		this.setMilliseconds(0);

		if (this.getDate() != d) {




			for (var hr = 1, c = this.add(Date.HOUR, hr); c.getDate() != d; hr++, c = this.add(Date.HOUR, hr));

			this.setDate(d);
			this.setHours(c.getHours());
		}

		return this;
	},


	add : function(interval, value) {
		var d = this.clone();
		if (!interval || value === 0) return d;

		switch(interval.toLowerCase()) {
			case Date.MILLI:
				d.setMilliseconds(this.getMilliseconds() + value);
				break;
			case Date.SECOND:
				d.setSeconds(this.getSeconds() + value);
				break;
			case Date.MINUTE:
				d.setMinutes(this.getMinutes() + value);
				break;
			case Date.HOUR:
				d.setHours(this.getHours() + value);
				break;
			case Date.DAY:
				d.setDate(this.getDate() + value);
				break;
			case Date.MONTH:
				var day = this.getDate();
				if (day > 28) {
					day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate());
				}
				d.setDate(day);
				d.setMonth(this.getMonth() + value);
				break;
			case Date.YEAR:
				d.setFullYear(this.getFullYear() + value);
				break;
		}
		return d;
	},


	between : function(start, end) {
		var t = this.getTime();
		return start.getTime() <= t && t <= end.getTime();
	}
});



Date.prototype.format = Date.prototype.dateFormat;



if (Ext.isSafari && (navigator.userAgent.match(/WebKit\/(\d+)/)[1] || NaN) < 420) {
	Ext.apply(Date.prototype, {
		_xMonth : Date.prototype.setMonth,
		_xDate  : Date.prototype.setDate,



		setMonth : function(num) {
			if (num <= -1) {
				var n = Math.ceil(-num),
				back_year = Math.ceil(n / 12),
				month = (n % 12) ? 12 - n % 12 : 0;

				this.setFullYear(this.getFullYear() - back_year);

				return this._xMonth(month);
			} else {
				return this._xMonth(num);
			}
		},




		setDate : function(d) {


			return this.setTime(this.getTime() - (this.getDate() - d) * 864e5);
		}
	});
}





Ext.util.MixedCollection = function(allowFunctions, keyFn){
	this.items = [];
	this.map = {};
	this.keys = [];
	this.length = 0;
	this.addEvents(

		'clear',

		'add',

		'replace',

		'remove',
		'sort'
		);
	this.allowFunctions = allowFunctions === true;
	if(keyFn){
		this.getKey = keyFn;
	}
	Ext.util.MixedCollection.superclass.constructor.call(this);
};

Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, {


	allowFunctions : false,


	add : function(key, o){
		if(arguments.length == 1){
			o = arguments[0];
			key = this.getKey(o);
		}
		if(typeof key != 'undefined' && key !== null){
			var old = this.map[key];
			if(typeof old != 'undefined'){
				return this.replace(key, o);
			}
			this.map[key] = o;
		}
		this.length++;
		this.items.push(o);
		this.keys.push(key);
		this.fireEvent('add', this.length-1, o, key);
		return o;
	},


	getKey : function(o){
		return o.id;
	},


	replace : function(key, o){
		if(arguments.length == 1){
			o = arguments[0];
			key = this.getKey(o);
		}
		var old = this.map[key];
		if(typeof key == 'undefined' || key === null || typeof old == 'undefined'){
			return this.add(key, o);
		}
		var index = this.indexOfKey(key);
		this.items[index] = o;
		this.map[key] = o;
		this.fireEvent('replace', key, old, o);
		return o;
	},


	addAll : function(objs){
		if(arguments.length > 1 || Ext.isArray(objs)){
			var args = arguments.length > 1 ? arguments : objs;
			for(var i = 0, len = args.length; i < len; i++){
				this.add(args[i]);
			}
		}else{
			for(var key in objs){
				if(this.allowFunctions || typeof objs[key] != 'function'){
					this.add(key, objs[key]);
				}
			}
		}
	},


	each : function(fn, scope){
		var items = [].concat(this.items);
		for(var i = 0, len = items.length; i < len; i++){
			if(fn.call(scope || items[i], items[i], i, len) === false){
				break;
			}
		}
	},


	eachKey : function(fn, scope){
		for(var i = 0, len = this.keys.length; i < len; i++){
			fn.call(scope || window, this.keys[i], this.items[i], i, len);
		}
	},


	find : function(fn, scope){
		for(var i = 0, len = this.items.length; i < len; i++){
			if(fn.call(scope || window, this.items[i], this.keys[i])){
				return this.items[i];
			}
		}
		return null;
	},


	insert : function(index, key, o){
		if(arguments.length == 2){
			o = arguments[1];
			key = this.getKey(o);
		}
		if(this.containsKey(key)){
			this.suspendEvents();
			this.removeKey(key);
			this.resumeEvents();
		}
		if(index >= this.length){
			return this.add(key, o);
		}
		this.length++;
		this.items.splice(index, 0, o);
		if(typeof key != 'undefined' && key !== null){
			this.map[key] = o;
		}
		this.keys.splice(index, 0, key);
		this.fireEvent('add', index, o, key);
		return o;
	},


	remove : function(o){
		return this.removeAt(this.indexOf(o));
	},


	removeAt : function(index){
		if(index < this.length && index >= 0){
			this.length--;
			var o = this.items[index];
			this.items.splice(index, 1);
			var key = this.keys[index];
			if(typeof key != 'undefined'){
				delete this.map[key];
			}
			this.keys.splice(index, 1);
			this.fireEvent('remove', o, key);
			return o;
		}
		return false;
	},


	removeKey : function(key){
		return this.removeAt(this.indexOfKey(key));
	},


	getCount : function(){
		return this.length;
	},


	indexOf : function(o){
		return this.items.indexOf(o);
	},


	indexOfKey : function(key){
		return this.keys.indexOf(key);
	},


	item : function(key){
		var mk = this.map[key],
		item = mk !== undefined ? mk : (typeof key == 'number') ? this.items[key] : undefined;
		return typeof item != 'function' || this.allowFunctions ? item : null;
	},


	itemAt : function(index){
		return this.items[index];
	},


	key : function(key){
		return this.map[key];
	},


	contains : function(o){
		return this.indexOf(o) != -1;
	},


	containsKey : function(key){
		return typeof this.map[key] != 'undefined';
	},


	clear : function(){
		this.length = 0;
		this.items = [];
		this.keys = [];
		this.map = {};
		this.fireEvent('clear');
	},


	first : function(){
		return this.items[0];
	},


	last : function(){
		return this.items[this.length-1];
	},


	_sort : function(property, dir, fn){
		var i, len,
		dsc   = String(dir).toUpperCase() == 'DESC' ? -1 : 1,


		c     = [],
		keys  = this.keys,
		items = this.items;


		fn = fn || function(a, b) {
			return a - b;
		};


		for(i = 0, len = items.length; i < len; i++){
			c[c.length] = {
				key  : keys[i],
				value: items[i],
				index: i
			};
		}


		c.sort(function(a, b){
			var v = fn(a[property], b[property]) * dsc;
			if(v === 0){
				v = (a.index < b.index ? -1 : 1);
			}
			return v;
		});


		for(i = 0, len = c.length; i < len; i++){
			items[i] = c[i].value;
			keys[i]  = c[i].key;
		}

		this.fireEvent('sort', this);
	},


	sort : function(dir, fn){
		this._sort('value', dir, fn);
	},


	reorder: function(mapping) {
		this.suspendEvents();

		var items = this.items,
		index = 0,
		length = items.length,
		order = [],
		remaining = [],
		oldIndex;


		for (oldIndex in mapping) {
			order[mapping[oldIndex]] = items[oldIndex];
		}

		for (index = 0; index < length; index++) {
			if (mapping[index] == undefined) {
				remaining.push(items[index]);
			}
		}

		for (index = 0; index < length; index++) {
			if (order[index] == undefined) {
				order[index] = remaining.shift();
			}
		}

		this.clear();
		this.addAll(order);

		this.resumeEvents();
		this.fireEvent('sort', this);
	},


	keySort : function(dir, fn){
		this._sort('key', dir, fn || function(a, b){
			var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase();
			return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
		});
	},


	getRange : function(start, end){
		var items = this.items;
		if(items.length < 1){
			return [];
		}
		start = start || 0;
		end = Math.min(typeof end == 'undefined' ? this.length-1 : end, this.length-1);
		var i, r = [];
		if(start <= end){
			for(i = start; i <= end; i++) {
				r[r.length] = items[i];
			}
		}else{
			for(i = start; i >= end; i--) {
				r[r.length] = items[i];
			}
		}
		return r;
	},


	filter : function(property, value, anyMatch, caseSensitive){
		if(Ext.isEmpty(value, false)){
			return this.clone();
		}
		value = this.createValueMatcher(value, anyMatch, caseSensitive);
		return this.filterBy(function(o){
			return o && value.test(o[property]);
		});
	},


	filterBy : function(fn, scope){
		var r = new Ext.util.MixedCollection();
		r.getKey = this.getKey;
		var k = this.keys, it = this.items;
		for(var i = 0, len = it.length; i < len; i++){
			if(fn.call(scope||this, it[i], k[i])){
				r.add(k[i], it[i]);
			}
		}
		return r;
	},


	findIndex : function(property, value, start, anyMatch, caseSensitive){
		if(Ext.isEmpty(value, false)){
			return -1;
		}
		value = this.createValueMatcher(value, anyMatch, caseSensitive);
		return this.findIndexBy(function(o){
			return o && value.test(o[property]);
		}, null, start);
	},


	findIndexBy : function(fn, scope, start){
		var k = this.keys, it = this.items;
		for(var i = (start||0), len = it.length; i < len; i++){
			if(fn.call(scope||this, it[i], k[i])){
				return i;
			}
		}
		return -1;
	},


	createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) {
		if (!value.exec) {
			var er = Ext.escapeRe;
			value = String(value);

			if (anyMatch === true) {
				value = er(value);
			} else {
				value = '^' + er(value);
				if (exactMatch === true) {
					value += '$';
				}
			}
			value = new RegExp(value, caseSensitive ? '' : 'i');
		}
		return value;
	},


	clone : function(){
		var r = new Ext.util.MixedCollection();
		var k = this.keys, it = this.items;
		for(var i = 0, len = it.length; i < len; i++){
			r.add(k[i], it[i]);
		}
		r.getKey = this.getKey;
		return r;
	}
});

Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item;

Ext.AbstractManager = Ext.extend(Object, {
	typeName: 'type',

	constructor: function(config) {
		Ext.apply(this, config || {});


		this.all = new Ext.util.MixedCollection();

		this.types = {};
	},


	get : function(id){
		return this.all.get(id);
	},


	register: function(item) {
		this.all.add(item);
	},


	unregister: function(item) {
		this.all.remove(item);
	},


	registerType : function(type, cls){
		this.types[type] = cls;
		cls[this.typeName] = type;
	},


	isRegistered : function(type){
		return this.types[type] !== undefined;
	},


	create: function(config, defaultType) {
		var type        = config[this.typeName] || config.type || defaultType,
		Constructor = this.types[type];

		if (Constructor == undefined) {
			throw new Error(String.format("The '{0}' type has not been registered with this manager", type));
		}

		return new Constructor(config);
	},


	onAvailable : function(id, fn, scope){
		var all = this.all;

		all.on("add", function(index, o){
			if (o.id == id) {
				fn.call(scope || o, o);
				all.un("add", fn, scope);
			}
		});
	}
});
Ext.util.Format = function() {
	var trimRe         = /^\s+|\s+$/g,
	stripTagsRE    = /<\/?[^>]+>/gi,
	stripScriptsRe = /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,
	nl2brRe        = /\r?\n/g;

	return {

		ellipsis : function(value, len, word) {
			if (value && value.length > len) {
				if (word) {
					var vs    = value.substr(0, len - 2),
					index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));
					if (index == -1 || index < (len - 15)) {
						return value.substr(0, len - 3) + "...";
					} else {
						return vs.substr(0, index) + "...";
					}
				} else {
					return value.substr(0, len - 3) + "...";
				}
			}
			return value;
		},


		undef : function(value) {
			return value !== undefined ? value : "";
		},


		defaultValue : function(value, defaultValue) {
			return value !== undefined && value !== '' ? value : defaultValue;
		},


		htmlEncode : function(value) {
			return !value ? value : String(value).replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;").replace(/"/g, "&quot;");
		},


		htmlDecode : function(value) {
			return !value ? value : String(value).replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
		},


		trim : function(value) {
			return String(value).replace(trimRe, "");
		},


		substr : function(value, start, length) {
			return String(value).substr(start, length);
		},


		lowercase : function(value) {
			return String(value).toLowerCase();
		},


		uppercase : function(value) {
			return String(value).toUpperCase();
		},


		capitalize : function(value) {
			return !value ? value : value.charAt(0).toUpperCase() + value.substr(1).toLowerCase();
		},


		call : function(value, fn) {
			if (arguments.length > 2) {
				var args = Array.prototype.slice.call(arguments, 2);
				args.unshift(value);
				return eval(fn).apply(window, args);
			} else {
				return eval(fn).call(window, value);
			}
		},


		usMoney : function(v) {
			v = (Math.round((v-0)*100))/100;
			v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v);
			v = String(v);
			var ps = v.split('.'),
			whole = ps[0],
			sub = ps[1] ? '.'+ ps[1] : '.00',
			r = /(\d+)(\d{3})/;
			while (r.test(whole)) {
				whole = whole.replace(r, '$1' + ',' + '$2');
			}
			v = whole + sub;
			if (v.charAt(0) == '-') {
				return '-$' + v.substr(1);
			}
			return "$" +  v;
		},


		date : function(v, format) {
			if (!v) {
				return "";
			}
			if (!Ext.isDate(v)) {
				v = new Date(Date.parse(v));
			}
			return v.dateFormat(format || "m/d/Y");
		},


		dateRenderer : function(format) {
			return function(v) {
				return Ext.util.Format.date(v, format);
			};
		},


		stripTags : function(v) {
			return !v ? v : String(v).replace(stripTagsRE, "");
		},


		stripScripts : function(v) {
			return !v ? v : String(v).replace(stripScriptsRe, "");
		},


		fileSize : function(size) {
			if (size < 1024) {
				return size + " bytes";
			} else if (size < 1048576) {
				return (Math.round(((size*10) / 1024))/10) + " KB";
			} else {
				return (Math.round(((size*10) / 1048576))/10) + " MB";
			}
		},


		math : function(){
			var fns = {};

			return function(v, a){
				if (!fns[a]) {
					fns[a] = new Function('v', 'return v ' + a + ';');
				}
				return fns[a](v);
			};
		}(),


		round : function(value, precision) {
			var result = Number(value);
			if (typeof precision == 'number') {
				precision = Math.pow(10, precision);
				result = Math.round(value * precision) / precision;
			}
			return result;
		},


		number: function(v, format) {
			if (!format) {
				return v;
			}
			v = Ext.num(v, NaN);
			if (isNaN(v)) {
				return '';
			}
			var comma = ',',
			dec   = '.',
			i18n  = false,
			neg   = v < 0;

			v = Math.abs(v);
			if (format.substr(format.length - 2) == '/i') {
				format = format.substr(0, format.length - 2);
				i18n   = true;
				comma  = '.';
				dec    = ',';
			}

			var hasComma = format.indexOf(comma) != -1,
			psplit   = (i18n ? format.replace(/[^\d\,]/g, '') : format.replace(/[^\d\.]/g, '')).split(dec);

			if (1 < psplit.length) {
				v = v.toFixed(psplit[1].length);
			} else if(2 < psplit.length) {
				throw ('NumberFormatException: invalid format, formats should have no more than 1 period: ' + format);
			} else {
				v = v.toFixed(0);
			}

			var fnum = v.toString();

			psplit = fnum.split('.');

			if (hasComma) {
				var cnum = psplit[0],
				parr = [],
				j    = cnum.length,
				m    = Math.floor(j / 3),
				n    = cnum.length % 3 || 3,
				i;

				for (i = 0; i < j; i += n) {
					if (i != 0) {
						n = 3;
					}

					parr[parr.length] = cnum.substr(i, n);
					m -= 1;
				}
				fnum = parr.join(comma);
				if (psplit[1]) {
					fnum += dec + psplit[1];
				}
			} else {
				if (psplit[1]) {
					fnum = psplit[0] + dec + psplit[1];
				}
			}

			return (neg ? '-' : '') + format.replace(/[\d,?\.?]+/, fnum);
		},


		numberRenderer : function(format) {
			return function(v) {
				return Ext.util.Format.number(v, format);
			};
		},


		plural : function(v, s, p) {
			return v +' ' + (v == 1 ? s : (p ? p : s+'s'));
		},


		nl2br : function(v) {
			return Ext.isEmpty(v) ? '' : v.replace(nl2brRe, '<br/>');
		}
	};
}();

Ext.XTemplate = function(){
	Ext.XTemplate.superclass.constructor.apply(this, arguments);

	var me = this,
	s = me.html,
	re = /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/,
	nameRe = /^<tpl\b[^>]*?for="(.*?)"/,
	ifRe = /^<tpl\b[^>]*?if="(.*?)"/,
	execRe = /^<tpl\b[^>]*?exec="(.*?)"/,
	m,
	id = 0,
	tpls = [],
	VALUES = 'values',
	PARENT = 'parent',
	XINDEX = 'xindex',
	XCOUNT = 'xcount',
	RETURN = 'return ',
	WITHVALUES = 'with(values){ ';

	s = ['<tpl>', s, '</tpl>'].join('');

	while((m = s.match(re))){
		var m2 = m[0].match(nameRe),
		m3 = m[0].match(ifRe),
		m4 = m[0].match(execRe),
		exp = null,
		fn = null,
		exec = null,
		name = m2 && m2[1] ? m2[1] : '';

		if (m3) {
			exp = m3 && m3[1] ? m3[1] : null;
			if(exp){
				fn = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + RETURN +(Ext.util.Format.htmlDecode(exp))+'; }');
			}
		}
		if (m4) {
			exp = m4 && m4[1] ? m4[1] : null;
			if(exp){
				exec = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES +(Ext.util.Format.htmlDecode(exp))+'; }');
			}
		}
		if(name){
			switch(name){
				case '.':
					name = new Function(VALUES, PARENT, WITHVALUES + RETURN + VALUES + '; }');
					break;
				case '..':
					name = new Function(VALUES, PARENT, WITHVALUES + RETURN + PARENT + '; }');
					break;
				default:
					name = new Function(VALUES, PARENT, WITHVALUES + RETURN + name + '; }');
			}
		}
		tpls.push({
			id: id,
			target: name,
			exec: exec,
			test: fn,
			body: m[1]||''
		});
		s = s.replace(m[0], '{xtpl'+ id + '}');
		++id;
	}
	for(var i = tpls.length-1; i >= 0; --i){
		me.compileTpl(tpls[i]);
	}
	me.master = tpls[tpls.length-1];
	me.tpls = tpls;
};
Ext.extend(Ext.XTemplate, Ext.Template, {

	re : /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g,

	codeRe : /\{\[((?:\\\]|.|\n)*?)\]\}/g,


	applySubTemplate : function(id, values, parent, xindex, xcount){
		var me = this,
		len,
		t = me.tpls[id],
		vs,
		buf = [];
		if ((t.test && !t.test.call(me, values, parent, xindex, xcount)) ||
			(t.exec && t.exec.call(me, values, parent, xindex, xcount))) {
			return '';
		}
		vs = t.target ? t.target.call(me, values, parent) : values;
		len = vs.length;
		parent = t.target ? values : parent;
		if(t.target && Ext.isArray(vs)){
			for(var i = 0, len = vs.length; i < len; i++){
				buf[buf.length] = t.compiled.call(me, vs[i], parent, i+1, len);
			}
			return buf.join('');
		}
		return t.compiled.call(me, vs, parent, xindex, xcount);
	},


	compileTpl : function(tpl){
		var fm = Ext.util.Format,
		useF = this.disableFormats !== true,
		sep = Ext.isGecko ? "+" : ",",
		body;

		function fn(m, name, format, args, math){
			if(name.substr(0, 4) == 'xtpl'){
				return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent, xindex, xcount)'+sep+"'";
			}
			var v;
			if(name === '.'){
				v = 'values';
			}else if(name === '#'){
				v = 'xindex';
			}else if(name.indexOf('.') != -1){
				v = name;
			}else{
				v = "values['" + name + "']";
			}
			if(math){
				v = '(' + v + math + ')';
			}
			if (format && useF) {
				args = args ? ',' + args : "";
				if(format.substr(0, 5) != "this."){
					format = "fm." + format + '(';
				}else{
					format = 'this.call("'+ format.substr(5) + '", ';
					args = ", values";
				}
			} else {
				args= '';
				format = "("+v+" === undefined ? '' : ";
			}
			return "'"+ sep + format + v + args + ")"+sep+"'";
		}

		function codeFn(m, code){

			return "'" + sep + '(' + code.replace(/\\'/g, "'") + ')' + sep + "'";
		}


		if(Ext.isGecko){
			body = "tpl.compiled = function(values, parent, xindex, xcount){ return '" +
			tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn) +
			"';};";
		}else{
			body = ["tpl.compiled = function(values, parent, xindex, xcount){ return ['"];
			body.push(tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn));
			body.push("'].join('');};");
			body = body.join('');
		}
		eval(body);
		return this;
	},


	applyTemplate : function(values){
		return this.master.compiled.call(this, values, {}, 1, 1);
	},


	compile : function(){
		return this;
	}





});

Ext.XTemplate.prototype.apply = Ext.XTemplate.prototype.applyTemplate;


Ext.XTemplate.from = function(el){
	el = Ext.getDom(el);
	return new Ext.XTemplate(el.value || el.innerHTML);
};

Ext.util.CSS = function(){
	var rules = null;
	var doc = document;

	var camelRe = /(-[a-z])/gi;
	var camelFn = function(m, a){
		return a.charAt(1).toUpperCase();
	};

	return {

		createStyleSheet : function(cssText, id){
			var ss;
			var head = doc.getElementsByTagName("head")[0];
			var rules = doc.createElement("style");
			rules.setAttribute("type", "text/css");
			if(id){
				rules.setAttribute("id", id);
			}
			if(Ext.isIE){
				head.appendChild(rules);
				ss = rules.styleSheet;
				ss.cssText = cssText;
			}else{
				try{
					rules.appendChild(doc.createTextNode(cssText));
				}catch(e){
					rules.cssText = cssText;
				}
				head.appendChild(rules);
				ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]);
			}
			this.cacheStyleSheet(ss);
			return ss;
		},


		removeStyleSheet : function(id){
			var existing = doc.getElementById(id);
			if(existing){
				existing.parentNode.removeChild(existing);
			}
		},


		swapStyleSheet : function(id, url){
			this.removeStyleSheet(id);
			var ss = doc.createElement("link");
			ss.setAttribute("rel", "stylesheet");
			ss.setAttribute("type", "text/css");
			ss.setAttribute("id", id);
			ss.setAttribute("href", url);
			doc.getElementsByTagName("head")[0].appendChild(ss);
		},


		refreshCache : function(){
			return this.getRules(true);
		},


		cacheStyleSheet : function(ss){
			if(!rules){
				rules = {};
			}
			try{
				var ssRules = ss.cssRules || ss.rules;
				for(var j = ssRules.length-1; j >= 0; --j){
					rules[ssRules[j].selectorText.toLowerCase()] = ssRules[j];
				}
			}catch(e){}
		},


		getRules : function(refreshCache){
			if(rules === null || refreshCache){
				rules = {};
				var ds = doc.styleSheets;
				for(var i =0, len = ds.length; i < len; i++){
					try{
						this.cacheStyleSheet(ds[i]);
					}catch(e){}
				}
			}
			return rules;
		},


		getRule : function(selector, refreshCache){
			var rs = this.getRules(refreshCache);
			if(!Ext.isArray(selector)){
				return rs[selector.toLowerCase()];
			}
			for(var i = 0; i < selector.length; i++){
				if(rs[selector[i]]){
					return rs[selector[i].toLowerCase()];
				}
			}
			return null;
		},



		updateRule : function(selector, property, value){
			if(!Ext.isArray(selector)){
				var rule = this.getRule(selector);
				if(rule){
					rule.style[property.replace(camelRe, camelFn)] = value;
					return true;
				}
			}else{
				for(var i = 0; i < selector.length; i++){
					if(this.updateRule(selector[i], property, value)){
						return true;
					}
				}
			}
			return false;
		}
	};
}();
Ext.util.ClickRepeater = Ext.extend(Ext.util.Observable, {

	constructor : function(el, config){
		this.el = Ext.get(el);
		this.el.unselectable();

		Ext.apply(this, config);

		this.addEvents(

			"mousedown",

			"click",

			"mouseup"
			);

		if(!this.disabled){
			this.disabled = true;
			this.enable();
		}


		if(this.handler){
			this.on("click", this.handler,  this.scope || this);
		}

		Ext.util.ClickRepeater.superclass.constructor.call(this);
	},

	interval : 20,
	delay: 250,
	preventDefault : true,
	stopDefault : false,
	timer : 0,


	enable: function(){
		if(this.disabled){
			this.el.on('mousedown', this.handleMouseDown, this);
			if (Ext.isIE){
				this.el.on('dblclick', this.handleDblClick, this);
			}
			if(this.preventDefault || this.stopDefault){
				this.el.on('click', this.eventOptions, this);
			}
		}
		this.disabled = false;
	},


	disable: function( force){
		if(force || !this.disabled){
			clearTimeout(this.timer);
			if(this.pressClass){
				this.el.removeClass(this.pressClass);
			}
			Ext.getDoc().un('mouseup', this.handleMouseUp, this);
			this.el.removeAllListeners();
		}
		this.disabled = true;
	},


	setDisabled: function(disabled){
		this[disabled ? 'disable' : 'enable']();
	},

	eventOptions: function(e){
		if(this.preventDefault){
			e.preventDefault();
		}
		if(this.stopDefault){
			e.stopEvent();
		}
	},


	destroy : function() {
		this.disable(true);
		Ext.destroy(this.el);
		this.purgeListeners();
	},

	handleDblClick : function(e){
		clearTimeout(this.timer);
		this.el.blur();

		this.fireEvent("mousedown", this, e);
		this.fireEvent("click", this, e);
	},


	handleMouseDown : function(e){
		clearTimeout(this.timer);
		this.el.blur();
		if(this.pressClass){
			this.el.addClass(this.pressClass);
		}
		this.mousedownTime = new Date();

		Ext.getDoc().on("mouseup", this.handleMouseUp, this);
		this.el.on("mouseout", this.handleMouseOut, this);

		this.fireEvent("mousedown", this, e);
		this.fireEvent("click", this, e);


		if (this.accelerate) {
			this.delay = 400;
		}
		this.timer = this.click.defer(this.delay || this.interval, this, [e]);
	},


	click : function(e){
		this.fireEvent("click", this, e);
		this.timer = this.click.defer(this.accelerate ?
			this.easeOutExpo(this.mousedownTime.getElapsed(),
				400,
				-390,
				12000) :
			this.interval, this, [e]);
	},

	easeOutExpo : function (t, b, c, d) {
		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
	},


	handleMouseOut : function(){
		clearTimeout(this.timer);
		if(this.pressClass){
			this.el.removeClass(this.pressClass);
		}
		this.el.on("mouseover", this.handleMouseReturn, this);
	},


	handleMouseReturn : function(){
		this.el.un("mouseover", this.handleMouseReturn, this);
		if(this.pressClass){
			this.el.addClass(this.pressClass);
		}
		this.click();
	},


	handleMouseUp : function(e){
		clearTimeout(this.timer);
		this.el.un("mouseover", this.handleMouseReturn, this);
		this.el.un("mouseout", this.handleMouseOut, this);
		Ext.getDoc().un("mouseup", this.handleMouseUp, this);
		this.el.removeClass(this.pressClass);
		this.fireEvent("mouseup", this, e);
	}
});
Ext.KeyNav = function(el, config){
	this.el = Ext.get(el);
	Ext.apply(this, config);
	if(!this.disabled){
		this.disabled = true;
		this.enable();
	}
};

Ext.KeyNav.prototype = {

	disabled : false,

	defaultEventAction: "stopEvent",

	forceKeyDown : false,


	relay : function(e){
		var k = e.getKey(),
		h = this.keyToHandler[k];
		if(h && this[h]){
			if(this.doRelay(e, this[h], h) !== true){
				e[this.defaultEventAction]();
			}
		}
	},


	doRelay : function(e, h, hname){
		return h.call(this.scope || this, e, hname);
	},


	enter : false,
	left : false,
	right : false,
	up : false,
	down : false,
	tab : false,
	esc : false,
	pageUp : false,
	pageDown : false,
	del : false,
	home : false,
	end : false,


	keyToHandler : {
		37 : "left",
		39 : "right",
		38 : "up",
		40 : "down",
		33 : "pageUp",
		34 : "pageDown",
		46 : "del",
		36 : "home",
		35 : "end",
		13 : "enter",
		27 : "esc",
		9  : "tab"
	},

	stopKeyUp: function(e) {
		var k = e.getKey();

		if (k >= 37 && k <= 40) {


			e.stopEvent();
		}
	},


	destroy: function(){
		this.disable();
	},


	enable: function() {
		if (this.disabled) {
			if (Ext.isSafari2) {

				this.el.on('keyup', this.stopKeyUp, this);
			}

			this.el.on(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
			this.disabled = false;
		}
	},


	disable: function() {
		if (!this.disabled) {
			if (Ext.isSafari2) {

				this.el.un('keyup', this.stopKeyUp, this);
			}

			this.el.un(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
			this.disabled = true;
		}
	},


	setDisabled : function(disabled){
		this[disabled ? "disable" : "enable"]();
	},


	isKeydown: function(){
		return this.forceKeyDown || Ext.EventManager.useKeydown;
	}
};

Ext.KeyMap = function(el, config, eventName){
	this.el  = Ext.get(el);
	this.eventName = eventName || "keydown";
	this.bindings = [];
	if(config){
		this.addBinding(config);
	}
	this.enable();
};

Ext.KeyMap.prototype = {

	stopEvent : false,


	addBinding : function(config){
		if(Ext.isArray(config)){
			Ext.each(config, function(c){
				this.addBinding(c);
			}, this);
			return;
		}
		var keyCode = config.key,
		fn = config.fn || config.handler,
		scope = config.scope;

		if (config.stopEvent) {
			this.stopEvent = config.stopEvent;
		}

		if(typeof keyCode == "string"){
			var ks = [];
			var keyString = keyCode.toUpperCase();
			for(var j = 0, len = keyString.length; j < len; j++){
				ks.push(keyString.charCodeAt(j));
			}
			keyCode = ks;
		}
		var keyArray = Ext.isArray(keyCode);

		var handler = function(e){
			if(this.checkModifiers(config, e)){
				var k = e.getKey();
				if(keyArray){
					for(var i = 0, len = keyCode.length; i < len; i++){
						if(keyCode[i] == k){
							if(this.stopEvent){
								e.stopEvent();
							}
							fn.call(scope || window, k, e);
							return;
						}
					}
				}else{
					if(k == keyCode){
						if(this.stopEvent){
							e.stopEvent();
						}
						fn.call(scope || window, k, e);
					}
				}
			}
		};
		this.bindings.push(handler);
	},


	checkModifiers: function(config, e){
		var val, key, keys = ['shift', 'ctrl', 'alt'];
		for (var i = 0, len = keys.length; i < len; ++i){
			key = keys[i];
			val = config[key];
			if(!(val === undefined || (val === e[key + 'Key']))){
				return false;
			}
		}
		return true;
	},


	on : function(key, fn, scope){
		var keyCode, shift, ctrl, alt;
		if(typeof key == "object" && !Ext.isArray(key)){
			keyCode = key.key;
			shift = key.shift;
			ctrl = key.ctrl;
			alt = key.alt;
		}else{
			keyCode = key;
		}
		this.addBinding({
			key: keyCode,
			shift: shift,
			ctrl: ctrl,
			alt: alt,
			fn: fn,
			scope: scope
		});
	},


	handleKeyDown : function(e){
		if(this.enabled){
			var b = this.bindings;
			for(var i = 0, len = b.length; i < len; i++){
				b[i].call(this, e);
			}
		}
	},


	isEnabled : function(){
		return this.enabled;
	},


	enable: function(){
		if(!this.enabled){
			this.el.on(this.eventName, this.handleKeyDown, this);
			this.enabled = true;
		}
	},


	disable: function(){
		if(this.enabled){
			this.el.removeListener(this.eventName, this.handleKeyDown, this);
			this.enabled = false;
		}
	},


	setDisabled : function(disabled){
		this[disabled ? "disable" : "enable"]();
	}
};
Ext.util.TextMetrics = function(){
	var shared;
	return {

		measure : function(el, text, fixedWidth){
			if(!shared){
				shared = Ext.util.TextMetrics.Instance(el, fixedWidth);
			}
			shared.bind(el);
			shared.setFixedWidth(fixedWidth || 'auto');
			return shared.getSize(text);
		},


		createInstance : function(el, fixedWidth){
			return Ext.util.TextMetrics.Instance(el, fixedWidth);
		}
	};
}();

Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){
	var ml = new Ext.Element(document.createElement('div'));
	document.body.appendChild(ml.dom);
	ml.position('absolute');
	ml.setLeftTop(-1000, -1000);
	ml.hide();

	if(fixedWidth){
		ml.setWidth(fixedWidth);
	}

	var instance = {

		getSize : function(text){
			ml.update(text);
			var s = ml.getSize();
			ml.update('');
			return s;
		},


		bind : function(el){
			ml.setStyle(
				Ext.fly(el).getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing')
				);
		},


		setFixedWidth : function(width){
			ml.setWidth(width);
		},


		getWidth : function(text){
			ml.dom.style.width = 'auto';
			return this.getSize(text).width;
		},


		getHeight : function(text){
			return this.getSize(text).height;
		}
	};

	instance.bind(bindTo);

	return instance;
};

Ext.Element.addMethods({

	getTextWidth : function(text, min, max){
		return (Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000);
	}
});

Ext.util.Cookies = {

	set : function(name, value){
		var argv = arguments;
		var argc = arguments.length;
		var expires = (argc > 2) ? argv[2] : null;
		var path = (argc > 3) ? argv[3] : '/';
		var domain = (argc > 4) ? argv[4] : null;
		var secure = (argc > 5) ? argv[5] : false;
		document.cookie = name + "=" + escape(value) + ((expires === null) ? "" : ("; expires=" + expires.toGMTString())) + ((path === null) ? "" : ("; path=" + path)) + ((domain === null) ? "" : ("; domain=" + domain)) + ((secure === true) ? "; secure" : "");
	},


	get : function(name){
		var arg = name + "=";
		var alen = arg.length;
		var clen = document.cookie.length;
		var i = 0;
		var j = 0;
		while(i < clen){
			j = i + alen;
			if(document.cookie.substring(i, j) == arg){
				return Ext.util.Cookies.getCookieVal(j);
			}
			i = document.cookie.indexOf(" ", i) + 1;
			if(i === 0){
				break;
			}
		}
		return null;
	},


	clear : function(name){
		if(Ext.util.Cookies.get(name)){
			document.cookie = name + "=" + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
		}
	},

	getCookieVal : function(offset){
		var endstr = document.cookie.indexOf(";", offset);
		if(endstr == -1){
			endstr = document.cookie.length;
		}
		return unescape(document.cookie.substring(offset, endstr));
	}
};
Ext.handleError = function(e) {
	throw e;
};


Ext.Error = function(message) {

	this.message = (this.lang[message]) ? this.lang[message] : message;
};

Ext.Error.prototype = new Error();
Ext.apply(Ext.Error.prototype, {

	lang: {},

	name: 'Ext.Error',

	getName : function() {
		return this.name;
	},

	getMessage : function() {
		return this.message;
	},

	toJson : function() {
		return Ext.encode(this);
	}
});

Ext.ComponentMgr = function(){
	var all = new Ext.util.MixedCollection();
	var types = {};
	var ptypes = {};

	return {

		register : function(c){
			all.add(c);
		},


		unregister : function(c){
			all.remove(c);
		},


		get : function(id){
			return all.get(id);
		},


		onAvailable : function(id, fn, scope){
			all.on("add", function(index, o){
				if(o.id == id){
					fn.call(scope || o, o);
					all.un("add", fn, scope);
				}
			});
		},


		all : all,


		types : types,


		ptypes: ptypes,


		isRegistered : function(xtype){
			return types[xtype] !== undefined;
		},


		isPluginRegistered : function(ptype){
			return ptypes[ptype] !== undefined;
		},


		registerType : function(xtype, cls){
			types[xtype] = cls;
			cls.xtype = xtype;
		},


		create : function(config, defaultType){
			return config.render ? config : new types[config.xtype || defaultType](config);
		},


		registerPlugin : function(ptype, cls){
			ptypes[ptype] = cls;
			cls.ptype = ptype;
		},


		createPlugin : function(config, defaultType){
			var PluginCls = ptypes[config.ptype || defaultType];
			if (PluginCls.init) {
				return PluginCls;
			} else {
				return new PluginCls(config);
			}
		}
	};
}();


Ext.reg = Ext.ComponentMgr.registerType;

Ext.preg = Ext.ComponentMgr.registerPlugin;

Ext.create = Ext.ComponentMgr.create;
Ext.Component = function(config){
	config = config || {};
	if(config.initialConfig){
		if(config.isAction){
			this.baseAction = config;
		}
		config = config.initialConfig;
	}else if(config.tagName || config.dom || Ext.isString(config)){
		config = {
			applyTo: config,
			id: config.id || config
			};
	}


	this.initialConfig = config;

	Ext.apply(this, config);
	this.addEvents(

		'added',

		'disable',

		'enable',

		'beforeshow',

		'show',

		'beforehide',

		'hide',

		'removed',

		'beforerender',

		'render',

		'afterrender',

		'beforedestroy',

		'destroy',

		'beforestaterestore',

		'staterestore',

		'beforestatesave',

		'statesave'
		);
	this.getId();
	Ext.ComponentMgr.register(this);
	Ext.Component.superclass.constructor.call(this);

	if(this.baseAction){
		this.baseAction.addComponent(this);
	}

	this.initComponent();

	if(this.plugins){
		if(Ext.isArray(this.plugins)){
			for(var i = 0, len = this.plugins.length; i < len; i++){
				this.plugins[i] = this.initPlugin(this.plugins[i]);
			}
		}else{
			this.plugins = this.initPlugin(this.plugins);
		}
	}

	if(this.stateful !== false){
		this.initState();
	}

	if(this.applyTo){
		this.applyToMarkup(this.applyTo);
		delete this.applyTo;
	}else if(this.renderTo){
		this.render(this.renderTo);
		delete this.renderTo;
	}
};


Ext.Component.AUTO_ID = 1000;

Ext.extend(Ext.Component, Ext.util.Observable, {

















	disabled : false,

	hidden : false,







	autoEl : 'div',


	disabledClass : 'x-item-disabled',

	allowDomMove : true,

	autoShow : false,

	hideMode : 'display',

	hideParent : false,





	rendered : false,







	tplWriteMode : 'overwrite',




	bubbleEvents: [],



	ctype : 'Ext.Component',


	actionMode : 'el',


	getActionEl : function(){
		return this[this.actionMode];
	},

	initPlugin : function(p){
		if(p.ptype && !Ext.isFunction(p.init)){
			p = Ext.ComponentMgr.createPlugin(p);
		}else if(Ext.isString(p)){
			p = Ext.ComponentMgr.createPlugin({
				ptype: p
			});
		}
		p.init(this);
		return p;
	},


	initComponent : function(){

		if(this.listeners){
			this.on(this.listeners);
			delete this.listeners;
		}
		this.enableBubble(this.bubbleEvents);
	},


	render : function(container, position){
		if(!this.rendered && this.fireEvent('beforerender', this) !== false){
			if(!container && this.el){
				this.el = Ext.get(this.el);
				container = this.el.dom.parentNode;
				this.allowDomMove = false;
			}
			this.container = Ext.get(container);
			if(this.ctCls){
				this.container.addClass(this.ctCls);
			}
			this.rendered = true;
			if(position !== undefined){
				if(Ext.isNumber(position)){
					position = this.container.dom.childNodes[position];
				}else{
					position = Ext.getDom(position);
				}
			}
			this.onRender(this.container, position || null);
			if(this.autoShow){
				this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]);
			}
			if(this.cls){
				this.el.addClass(this.cls);
				delete this.cls;
			}
			if(this.style){
				this.el.applyStyles(this.style);
				delete this.style;
			}
			if(this.overCls){
				this.el.addClassOnOver(this.overCls);
			}
			this.fireEvent('render', this);




			var contentTarget = this.getContentTarget();
			if (this.html){
				contentTarget.update(Ext.DomHelper.markup(this.html));
				delete this.html;
			}
			if (this.contentEl){
				var ce = Ext.getDom(this.contentEl);
				Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']);
				contentTarget.appendChild(ce);
			}
			if (this.tpl) {
				if (!this.tpl.compile) {
					this.tpl = new Ext.XTemplate(this.tpl);
				}
				if (this.data) {
					this.tpl[this.tplWriteMode](contentTarget, this.data);
					delete this.data;
				}
			}
			this.afterRender(this.container);


			if(this.hidden){

				this.doHide();
			}
			if(this.disabled){

				this.disable(true);
			}

			if(this.stateful !== false){
				this.initStateEvents();
			}
			this.fireEvent('afterrender', this);
		}
		return this;
	},



	update: function(htmlOrData, loadScripts, cb) {
		var contentTarget = this.getContentTarget();
		if (this.tpl && typeof htmlOrData !== "string") {
			this.tpl[this.tplWriteMode](contentTarget, htmlOrData || {});
		} else {
			var html = Ext.isObject(htmlOrData) ? Ext.DomHelper.markup(htmlOrData) : htmlOrData;
			contentTarget.update(html, loadScripts, cb);
		}
	},



	onAdded : function(container, pos) {
		this.ownerCt = container;
		this.initRef();
		this.fireEvent('added', this, container, pos);
	},


	onRemoved : function() {
		this.removeRef();
		this.fireEvent('removed', this, this.ownerCt);
		delete this.ownerCt;
	},


	initRef : function() {

		if(this.ref && !this.refOwner){
			var levels = this.ref.split('/'),
			last = levels.length,
			i = 0,
			t = this;

			while(t && i < last){
				t = t.ownerCt;
				++i;
			}
			if(t){
				t[this.refName = levels[--i]] = this;

				this.refOwner = t;
			}
		}
	},

	removeRef : function() {
		if (this.refOwner && this.refName) {
			delete this.refOwner[this.refName];
			delete this.refOwner;
		}
	},


	initState : function(){
		if(Ext.state.Manager){
			var id = this.getStateId();
			if(id){
				var state = Ext.state.Manager.get(id);
				if(state){
					if(this.fireEvent('beforestaterestore', this, state) !== false){
						this.applyState(Ext.apply({}, state));
						this.fireEvent('staterestore', this, state);
					}
				}
			}
		}
	},


	getStateId : function(){
		return this.stateId || ((/^(ext-comp-|ext-gen)/).test(String(this.id)) ? null : this.id);
	},


	initStateEvents : function(){
		if(this.stateEvents){
			for(var i = 0, e; e = this.stateEvents[i]; i++){
				this.on(e, this.saveState, this, {
					delay:100
				});
			}
		}
	},


	applyState : function(state){
		if(state){
			Ext.apply(this, state);
		}
	},


	getState : function(){
		return null;
	},


	saveState : function(){
		if(Ext.state.Manager && this.stateful !== false){
			var id = this.getStateId();
			if(id){
				var state = this.getState();
				if(this.fireEvent('beforestatesave', this, state) !== false){
					Ext.state.Manager.set(id, state);
					this.fireEvent('statesave', this, state);
				}
			}
		}
	},


	applyToMarkup : function(el){
		this.allowDomMove = false;
		this.el = Ext.get(el);
		this.render(this.el.dom.parentNode);
	},


	addClass : function(cls){
		if(this.el){
			this.el.addClass(cls);
		}else{
			this.cls = this.cls ? this.cls + ' ' + cls : cls;
		}
		return this;
	},


	removeClass : function(cls){
		if(this.el){
			this.el.removeClass(cls);
		}else if(this.cls){
			this.cls = this.cls.split(' ').remove(cls).join(' ');
		}
		return this;
	},



	onRender : function(ct, position){
		if(!this.el && this.autoEl){
			if(Ext.isString(this.autoEl)){
				this.el = document.createElement(this.autoEl);
			}else{
				var div = document.createElement('div');
				Ext.DomHelper.overwrite(div, this.autoEl);
				this.el = div.firstChild;
			}
			if (!this.el.id) {
				this.el.id = this.getId();
			}
		}
		if(this.el){
			this.el = Ext.get(this.el);
			if(this.allowDomMove !== false){
				ct.dom.insertBefore(this.el.dom, position);
				if (div) {
					Ext.removeNode(div);
					div = null;
				}
			}
		}
	},


	getAutoCreate : function(){
		var cfg = Ext.isObject(this.autoCreate) ?
		this.autoCreate : Ext.apply({}, this.defaultAutoCreate);
		if(this.id && !cfg.id){
			cfg.id = this.id;
		}
		return cfg;
	},


	afterRender : Ext.emptyFn,


	destroy : function(){
		if(!this.isDestroyed){
			if(this.fireEvent('beforedestroy', this) !== false){
				this.destroying = true;
				this.beforeDestroy();
				if(this.ownerCt && this.ownerCt.remove){
					this.ownerCt.remove(this, false);
				}
				if(this.rendered){
					this.el.remove();
					if(this.actionMode == 'container' || this.removeMode == 'container'){
						this.container.remove();
					}
				}

				if(this.focusTask && this.focusTask.cancel){
					this.focusTask.cancel();
				}
				this.onDestroy();
				Ext.ComponentMgr.unregister(this);
				this.fireEvent('destroy', this);
				this.purgeListeners();
				this.destroying = false;
				this.isDestroyed = true;
			}
		}
	},

	deleteMembers : function(){
		var args = arguments;
		for(var i = 0, len = args.length; i < len; ++i){
			delete this[args[i]];
		}
	},


	beforeDestroy : Ext.emptyFn,


	onDestroy  : Ext.emptyFn,


	getEl : function(){
		return this.el;
	},


	getContentTarget : function(){
		return this.el;
	},


	getId : function(){
		return this.id || (this.id = 'ext-comp-' + (++Ext.Component.AUTO_ID));
	},


	getItemId : function(){
		return this.itemId || this.getId();
	},


	focus : function(selectText, delay){
		if(delay){
			this.focusTask = new Ext.util.DelayedTask(this.focus, this, [selectText, false]);
			this.focusTask.delay(Ext.isNumber(delay) ? delay : 10);
			return this;
		}
		if(this.rendered && !this.isDestroyed){
			this.el.focus();
			if(selectText === true){
				this.el.dom.select();
			}
		}
		return this;
	},


	blur : function(){
		if(this.rendered){
			this.el.blur();
		}
		return this;
	},


	disable : function( silent){
		if(this.rendered){
			this.onDisable();
		}
		this.disabled = true;
		if(silent !== true){
			this.fireEvent('disable', this);
		}
		return this;
	},


	onDisable : function(){
		this.getActionEl().addClass(this.disabledClass);
		this.el.dom.disabled = true;
	},


	enable : function(){
		if(this.rendered){
			this.onEnable();
		}
		this.disabled = false;
		this.fireEvent('enable', this);
		return this;
	},


	onEnable : function(){
		this.getActionEl().removeClass(this.disabledClass);
		this.el.dom.disabled = false;
	},


	setDisabled : function(disabled){
		return this[disabled ? 'disable' : 'enable']();
	},


	show : function(){
		if(this.fireEvent('beforeshow', this) !== false){
			this.hidden = false;
			if(this.autoRender){
				this.render(Ext.isBoolean(this.autoRender) ? Ext.getBody() : this.autoRender);
			}
			if(this.rendered){
				this.onShow();
			}
			this.fireEvent('show', this);
		}
		return this;
	},


	onShow : function(){
		this.getVisibilityEl().removeClass('x-hide-' + this.hideMode);
	},


	hide : function(){
		if(this.fireEvent('beforehide', this) !== false){
			this.doHide();
			this.fireEvent('hide', this);
		}
		return this;
	},


	doHide: function(){
		this.hidden = true;
		if(this.rendered){
			this.onHide();
		}
	},


	onHide : function(){
		this.getVisibilityEl().addClass('x-hide-' + this.hideMode);
	},


	getVisibilityEl : function(){
		return this.hideParent ? this.container : this.getActionEl();
	},


	setVisible : function(visible){
		return this[visible ? 'show' : 'hide']();
	},


	isVisible : function(){
		return this.rendered && this.getVisibilityEl().isVisible();
	},


	cloneConfig : function(overrides){
		overrides = overrides || {};
		var id = overrides.id || Ext.id();
		var cfg = Ext.applyIf(overrides, this.initialConfig);
		cfg.id = id;
		return new this.constructor(cfg);
	},


	getXType : function(){
		return this.constructor.xtype;
	},


	isXType : function(xtype, shallow){

		if (Ext.isFunction(xtype)){
			xtype = xtype.xtype;
		}else if (Ext.isObject(xtype)){
			xtype = xtype.constructor.xtype;
		}

		return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype;
	},


	getXTypes : function(){
		var tc = this.constructor;
		if(!tc.xtypes){
			var c = [], sc = this;
			while(sc && sc.constructor.xtype){
				c.unshift(sc.constructor.xtype);
				sc = sc.constructor.superclass;
			}
			tc.xtypeChain = c;
			tc.xtypes = c.join('/');
		}
		return tc.xtypes;
	},


	findParentBy : function(fn) {
		for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt);
		return p || null;
	},


	findParentByType : function(xtype, shallow){
		return this.findParentBy(function(c){
			return c.isXType(xtype, shallow);
		});
	},


	bubble : function(fn, scope, args){
		var p = this;
		while(p){
			if(fn.apply(scope || p, args || [p]) === false){
				break;
			}
			p = p.ownerCt;
		}
		return this;
	},


	getPositionEl : function(){
		return this.positionEl || this.el;
	},


	purgeListeners : function(){
		Ext.Component.superclass.purgeListeners.call(this);
		if(this.mons){
			this.on('beforedestroy', this.clearMons, this, {
				single: true
			});
		}
	},


	clearMons : function(){
		Ext.each(this.mons, function(m){
			m.item.un(m.ename, m.fn, m.scope);
		}, this);
		this.mons = [];
	},


	createMons: function(){
		if(!this.mons){
			this.mons = [];
			this.on('beforedestroy', this.clearMons, this, {
				single: true
			});
		}
	},


	mon : function(item, ename, fn, scope, opt){
		this.createMons();
		if(Ext.isObject(ename)){
			var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;

			var o = ename;
			for(var e in o){
				if(propRe.test(e)){
					continue;
				}
				if(Ext.isFunction(o[e])){

					this.mons.push({
						item: item,
						ename: e,
						fn: o[e],
						scope: o.scope
					});
					item.on(e, o[e], o.scope, o);
				}else{

					this.mons.push({
						item: item,
						ename: e,
						fn: o[e],
						scope: o.scope
					});
					item.on(e, o[e]);
				}
			}
			return;
		}

		this.mons.push({
			item: item,
			ename: ename,
			fn: fn,
			scope: scope
		});
		item.on(ename, fn, scope, opt);
	},


	mun : function(item, ename, fn, scope){
		var found, mon;
		this.createMons();
		for(var i = 0, len = this.mons.length; i < len; ++i){
			mon = this.mons[i];
			if(item === mon.item && ename == mon.ename && fn === mon.fn && scope === mon.scope){
				this.mons.splice(i, 1);
				item.un(ename, fn, scope);
				found = true;
				break;
			}
		}
		return found;
	},


	nextSibling : function(){
		if(this.ownerCt){
			var index = this.ownerCt.items.indexOf(this);
			if(index != -1 && index+1 < this.ownerCt.items.getCount()){
				return this.ownerCt.items.itemAt(index+1);
			}
		}
		return null;
	},


	previousSibling : function(){
		if(this.ownerCt){
			var index = this.ownerCt.items.indexOf(this);
			if(index > 0){
				return this.ownerCt.items.itemAt(index-1);
			}
		}
		return null;
	},


	getBubbleTarget : function(){
		return this.ownerCt;
	}
});

Ext.reg('component', Ext.Component);

Ext.Action = Ext.extend(Object, {








	constructor : function(config){
		this.initialConfig = config;
		this.itemId = config.itemId = (config.itemId || config.id || Ext.id());
		this.items = [];
	},


	isAction : true,


	setText : function(text){
		this.initialConfig.text = text;
		this.callEach('setText', [text]);
	},


	getText : function(){
		return this.initialConfig.text;
	},


	setIconClass : function(cls){
		this.initialConfig.iconCls = cls;
		this.callEach('setIconClass', [cls]);
	},


	getIconClass : function(){
		return this.initialConfig.iconCls;
	},


	setDisabled : function(v){
		this.initialConfig.disabled = v;
		this.callEach('setDisabled', [v]);
	},


	enable : function(){
		this.setDisabled(false);
	},


	disable : function(){
		this.setDisabled(true);
	},


	isDisabled : function(){
		return this.initialConfig.disabled;
	},


	setHidden : function(v){
		this.initialConfig.hidden = v;
		this.callEach('setVisible', [!v]);
	},


	show : function(){
		this.setHidden(false);
	},


	hide : function(){
		this.setHidden(true);
	},


	isHidden : function(){
		return this.initialConfig.hidden;
	},


	setHandler : function(fn, scope){
		this.initialConfig.handler = fn;
		this.initialConfig.scope = scope;
		this.callEach('setHandler', [fn, scope]);
	},


	each : function(fn, scope){
		Ext.each(this.items, fn, scope);
	},


	callEach : function(fnName, args){
		var cs = this.items;
		for(var i = 0, len = cs.length; i < len; i++){
			cs[i][fnName].apply(cs[i], args);
		}
	},


	addComponent : function(comp){
		this.items.push(comp);
		comp.on('destroy', this.removeComponent, this);
	},


	removeComponent : function(comp){
		this.items.remove(comp);
	},


	execute : function(){
		this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments);
	}
});

(function(){
	Ext.Layer = function(config, existingEl){
		config = config || {};
		var dh = Ext.DomHelper,
		cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body;

		if (existingEl) {
			this.dom = Ext.getDom(existingEl);
		}
		if(!this.dom){
			var o = config.dh || {
				tag: 'div',
				cls: 'x-layer'
			};
			this.dom = dh.append(pel, o);
		}
		if(config.cls){
			this.addClass(config.cls);
		}
		this.constrain = config.constrain !== false;
		this.setVisibilityMode(Ext.Element.VISIBILITY);
		if(config.id){
			this.id = this.dom.id = config.id;
		}else{
			this.id = Ext.id(this.dom);
		}
		this.zindex = config.zindex || this.getZIndex();
		this.position('absolute', this.zindex);
		if(config.shadow){
			this.shadowOffset = config.shadowOffset || 4;
			this.shadow = new Ext.Shadow({
				offset : this.shadowOffset,
				mode : config.shadow
			});
		}else{
			this.shadowOffset = 0;
		}
		this.useShim = config.shim !== false && Ext.useShims;
		this.useDisplay = config.useDisplay;
		this.hide();
	};

	var supr = Ext.Element.prototype;


	var shims = [];

	Ext.extend(Ext.Layer, Ext.Element, {

		getZIndex : function(){
			return this.zindex || parseInt((this.getShim() || this).getStyle('z-index'), 10) || 11000;
		},

		getShim : function(){
			if(!this.useShim){
				return null;
			}
			if(this.shim){
				return this.shim;
			}
			var shim = shims.shift();
			if(!shim){
				shim = this.createShim();
				shim.enableDisplayMode('block');
				shim.dom.style.display = 'none';
				shim.dom.style.visibility = 'visible';
			}
			var pn = this.dom.parentNode;
			if(shim.dom.parentNode != pn){
				pn.insertBefore(shim.dom, this.dom);
			}
			shim.setStyle('z-index', this.getZIndex()-2);
			this.shim = shim;
			return shim;
		},

		hideShim : function(){
			if(this.shim){
				this.shim.setDisplayed(false);
				shims.push(this.shim);
				delete this.shim;
			}
		},

		disableShadow : function(){
			if(this.shadow){
				this.shadowDisabled = true;
				this.shadow.hide();
				this.lastShadowOffset = this.shadowOffset;
				this.shadowOffset = 0;
			}
		},

		enableShadow : function(show){
			if(this.shadow){
				this.shadowDisabled = false;
				this.shadowOffset = this.lastShadowOffset;
				delete this.lastShadowOffset;
				if(show){
					this.sync(true);
				}
			}
		},




		sync : function(doShow){
			var shadow = this.shadow;
			if(!this.updating && this.isVisible() && (shadow || this.useShim)){
				var shim = this.getShim(),
				w = this.getWidth(),
				h = this.getHeight(),
				l = this.getLeft(true),
				t = this.getTop(true);

				if(shadow && !this.shadowDisabled){
					if(doShow && !shadow.isVisible()){
						shadow.show(this);
					}else{
						shadow.realign(l, t, w, h);
					}
					if(shim){
						if(doShow){
							shim.show();
						}

						var shadowAdj = shadow.el.getXY(), shimStyle = shim.dom.style,
						shadowSize = shadow.el.getSize();
						shimStyle.left = (shadowAdj[0])+'px';
						shimStyle.top = (shadowAdj[1])+'px';
						shimStyle.width = (shadowSize.width)+'px';
						shimStyle.height = (shadowSize.height)+'px';
					}
				}else if(shim){
					if(doShow){
						shim.show();
					}
					shim.setSize(w, h);
					shim.setLeftTop(l, t);
				}
			}
		},


		destroy : function(){
			this.hideShim();
			if(this.shadow){
				this.shadow.hide();
			}
			this.removeAllListeners();
			Ext.removeNode(this.dom);
			delete this.dom;
		},

		remove : function(){
			this.destroy();
		},


		beginUpdate : function(){
			this.updating = true;
		},


		endUpdate : function(){
			this.updating = false;
			this.sync(true);
		},


		hideUnders : function(negOffset){
			if(this.shadow){
				this.shadow.hide();
			}
			this.hideShim();
		},


		constrainXY : function(){
			if(this.constrain){
				var vw = Ext.lib.Dom.getViewWidth(),
				vh = Ext.lib.Dom.getViewHeight();
				var s = Ext.getDoc().getScroll();

				var xy = this.getXY();
				var x = xy[0], y = xy[1];
				var so = this.shadowOffset;
				var w = this.dom.offsetWidth+so, h = this.dom.offsetHeight+so;

				var moved = false;

				if((x + w) > vw+s.left){
					x = vw - w - so;
					moved = true;
				}
				if((y + h) > vh+s.top){
					y = vh - h - so;
					moved = true;
				}

				if(x < s.left){
					x = s.left;
					moved = true;
				}
				if(y < s.top){
					y = s.top;
					moved = true;
				}
				if(moved){
					if(this.avoidY){
						var ay = this.avoidY;
						if(y <= ay && (y+h) >= ay){
							y = ay-h-5;
						}
					}
					xy = [x, y];
					this.storeXY(xy);
					supr.setXY.call(this, xy);
					this.sync();
				}
			}
			return this;
		},

		getConstrainOffset : function(){
			return this.shadowOffset;
		},

		isVisible : function(){
			return this.visible;
		},


		showAction : function(){
			this.visible = true;
			if(this.useDisplay === true){
				this.setDisplayed('');
			}else if(this.lastXY){
				supr.setXY.call(this, this.lastXY);
			}else if(this.lastLT){
				supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);
			}
		},


		hideAction : function(){
			this.visible = false;
			if(this.useDisplay === true){
				this.setDisplayed(false);
			}else{
				this.setLeftTop(-10000,-10000);
			}
		},


		setVisible : function(v, a, d, c, e){
			if(v){
				this.showAction();
			}
			if(a && v){
				var cb = function(){
					this.sync(true);
					if(c){
						c();
					}
				}.createDelegate(this);
				supr.setVisible.call(this, true, true, d, cb, e);
			}else{
				if(!v){
					this.hideUnders(true);
				}
				var cb = c;
				if(a){
					cb = function(){
						this.hideAction();
						if(c){
							c();
						}
					}.createDelegate(this);
				}
				supr.setVisible.call(this, v, a, d, cb, e);
				if(v){
					this.sync(true);
				}else if(!a){
					this.hideAction();
				}
			}
			return this;
		},

		storeXY : function(xy){
			delete this.lastLT;
			this.lastXY = xy;
		},

		storeLeftTop : function(left, top){
			delete this.lastXY;
			this.lastLT = [left, top];
		},


		beforeFx : function(){
			this.beforeAction();
			return Ext.Layer.superclass.beforeFx.apply(this, arguments);
		},


		afterFx : function(){
			Ext.Layer.superclass.afterFx.apply(this, arguments);
			this.sync(this.isVisible());
		},


		beforeAction : function(){
			if(!this.updating && this.shadow){
				this.shadow.hide();
			}
		},


		setLeft : function(left){
			this.storeLeftTop(left, this.getTop(true));
			supr.setLeft.apply(this, arguments);
			this.sync();
			return this;
		},

		setTop : function(top){
			this.storeLeftTop(this.getLeft(true), top);
			supr.setTop.apply(this, arguments);
			this.sync();
			return this;
		},

		setLeftTop : function(left, top){
			this.storeLeftTop(left, top);
			supr.setLeftTop.apply(this, arguments);
			this.sync();
			return this;
		},

		setXY : function(xy, a, d, c, e){
			this.fixDisplay();
			this.beforeAction();
			this.storeXY(xy);
			var cb = this.createCB(c);
			supr.setXY.call(this, xy, a, d, cb, e);
			if(!a){
				cb();
			}
			return this;
		},


		createCB : function(c){
			var el = this;
			return function(){
				el.constrainXY();
				el.sync(true);
				if(c){
					c();
				}
			};
		},


		setX : function(x, a, d, c, e){
			this.setXY([x, this.getY()], a, d, c, e);
			return this;
		},


		setY : function(y, a, d, c, e){
			this.setXY([this.getX(), y], a, d, c, e);
			return this;
		},


		setSize : function(w, h, a, d, c, e){
			this.beforeAction();
			var cb = this.createCB(c);
			supr.setSize.call(this, w, h, a, d, cb, e);
			if(!a){
				cb();
			}
			return this;
		},


		setWidth : function(w, a, d, c, e){
			this.beforeAction();
			var cb = this.createCB(c);
			supr.setWidth.call(this, w, a, d, cb, e);
			if(!a){
				cb();
			}
			return this;
		},


		setHeight : function(h, a, d, c, e){
			this.beforeAction();
			var cb = this.createCB(c);
			supr.setHeight.call(this, h, a, d, cb, e);
			if(!a){
				cb();
			}
			return this;
		},


		setBounds : function(x, y, w, h, a, d, c, e){
			this.beforeAction();
			var cb = this.createCB(c);
			if(!a){
				this.storeXY([x, y]);
				supr.setXY.call(this, [x, y]);
				supr.setSize.call(this, w, h, a, d, cb, e);
				cb();
			}else{
				supr.setBounds.call(this, x, y, w, h, a, d, cb, e);
			}
			return this;
		},


		setZIndex : function(zindex){
			this.zindex = zindex;
			this.setStyle('z-index', zindex + 2);
			if(this.shadow){
				this.shadow.setZIndex(zindex + 1);
			}
			if(this.shim){
				this.shim.setStyle('z-index', zindex);
			}
			return this;
		}
	});
})();

Ext.Shadow = function(config) {
	Ext.apply(this, config);
	if (typeof this.mode != "string") {
		this.mode = this.defaultMode;
	}
	var o = this.offset,
	a = {
		h: 0
	},
	rad = Math.floor(this.offset / 2);
	switch (this.mode.toLowerCase()) {

		case "drop":
			a.w = 0;
			a.l = a.t = o;
			a.t -= 1;
			if (Ext.isIE) {
				a.l -= this.offset + rad;
				a.t -= this.offset + rad;
				a.w -= rad;
				a.h -= rad;
				a.t += 1;
			}
			break;
		case "sides":
			a.w = (o * 2);
			a.l = -o;
			a.t = o - 1;
			if (Ext.isIE) {
				a.l -= (this.offset - rad);
				a.t -= this.offset + rad;
				a.l += 1;
				a.w -= (this.offset - rad) * 2;
				a.w -= rad + 1;
				a.h -= 1;
			}
			break;
		case "frame":
			a.w = a.h = (o * 2);
			a.l = a.t = -o;
			a.t += 1;
			a.h -= 2;
			if (Ext.isIE) {
				a.l -= (this.offset - rad);
				a.t -= (this.offset - rad);
				a.l += 1;
				a.w -= (this.offset + rad + 1);
				a.h -= (this.offset + rad);
				a.h += 1;
			}
			break;
	};

	this.adjusts = a;
};

Ext.Shadow.prototype = {


	offset: 4,


	defaultMode: "drop",


	show: function(target) {
		target = Ext.get(target);
		if (!this.el) {
			this.el = Ext.Shadow.Pool.pull();
			if (this.el.dom.nextSibling != target.dom) {
				this.el.insertBefore(target);
			}
		}
		this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10) - 1);
		if (Ext.isIE) {
			this.el.dom.style.filter = "progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius=" + (this.offset) + ")";
		}
		this.realign(
			target.getLeft(true),
			target.getTop(true),
			target.getWidth(),
			target.getHeight()
			);
		this.el.dom.style.display = "block";
	},


	isVisible: function() {
		return this.el ? true: false;
	},


	realign: function(l, t, w, h) {
		if (!this.el) {
			return;
		}
		var a = this.adjusts,
		d = this.el.dom,
		s = d.style,
		iea = 0,
		sw = (w + a.w),
		sh = (h + a.h),
		sws = sw + "px",
		shs = sh + "px",
		cn,
		sww;
		s.left = (l + a.l) + "px";
		s.top = (t + a.t) + "px";
		if (s.width != sws || s.height != shs) {
			s.width = sws;
			s.height = shs;
			if (!Ext.isIE) {
				cn = d.childNodes;
				sww = Math.max(0, (sw - 12)) + "px";
				cn[0].childNodes[1].style.width = sww;
				cn[1].childNodes[1].style.width = sww;
				cn[2].childNodes[1].style.width = sww;
				cn[1].style.height = Math.max(0, (sh - 12)) + "px";
			}
		}
	},


	hide: function() {
		if (this.el) {
			this.el.dom.style.display = "none";
			Ext.Shadow.Pool.push(this.el);
			delete this.el;
		}
	},


	setZIndex: function(z) {
		this.zIndex = z;
		if (this.el) {
			this.el.setStyle("z-index", z);
		}
	}
};


Ext.Shadow.Pool = function() {
	var p = [],
	markup = Ext.isIE ?
	'<div class="x-ie-shadow"></div>':
	'<div class="x-shadow"><div class="xst"><div class="xstl"></div><div class="xstc"></div><div class="xstr"></div></div><div class="xsc"><div class="xsml"></div><div class="xsmc"></div><div class="xsmr"></div></div><div class="xsb"><div class="xsbl"></div><div class="xsbc"></div><div class="xsbr"></div></div></div>';
	return {
		pull: function() {
			var sh = p.shift();
			if (!sh) {
				sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup));
				sh.autoBoxAdjust = false;
			}
			return sh;
		},

		push: function(sh) {
			p.push(sh);
		}
	};
}();
Ext.BoxComponent = Ext.extend(Ext.Component, {




























	initComponent : function(){
		Ext.BoxComponent.superclass.initComponent.call(this);
		this.addEvents(

			'resize',

			'move'
			);
	},


	boxReady : false,

	deferHeight: false,


	setSize : function(w, h){


		if(typeof w == 'object'){
			h = w.height;
			w = w.width;
		}
		if (Ext.isDefined(w) && Ext.isDefined(this.boxMinWidth) && (w < this.boxMinWidth)) {
			w = this.boxMinWidth;
		}
		if (Ext.isDefined(h) && Ext.isDefined(this.boxMinHeight) && (h < this.boxMinHeight)) {
			h = this.boxMinHeight;
		}
		if (Ext.isDefined(w) && Ext.isDefined(this.boxMaxWidth) && (w > this.boxMaxWidth)) {
			w = this.boxMaxWidth;
		}
		if (Ext.isDefined(h) && Ext.isDefined(this.boxMaxHeight) && (h > this.boxMaxHeight)) {
			h = this.boxMaxHeight;
		}

		if(!this.boxReady){
			this.width  = w;
			this.height = h;
			return this;
		}


		if(this.cacheSizes !== false && this.lastSize && this.lastSize.width == w && this.lastSize.height == h){
			return this;
		}
		this.lastSize = {
			width: w,
			height: h
		};
		var adj = this.adjustSize(w, h),
		aw = adj.width,
		ah = adj.height,
		rz;
		if(aw !== undefined || ah !== undefined){
			rz = this.getResizeEl();
			if(!this.deferHeight && aw !== undefined && ah !== undefined){
				rz.setSize(aw, ah);
			}else if(!this.deferHeight && ah !== undefined){
				rz.setHeight(ah);
			}else if(aw !== undefined){
				rz.setWidth(aw);
			}
			this.onResize(aw, ah, w, h);
			this.fireEvent('resize', this, aw, ah, w, h);
		}
		return this;
	},


	setWidth : function(width){
		return this.setSize(width);
	},


	setHeight : function(height){
		return this.setSize(undefined, height);
	},


	getSize : function(){
		return this.getResizeEl().getSize();
	},


	getWidth : function(){
		return this.getResizeEl().getWidth();
	},


	getHeight : function(){
		return this.getResizeEl().getHeight();
	},


	getOuterSize : function(){
		var el = this.getResizeEl();
		return {
			width: el.getWidth() + el.getMargins('lr'),
			height: el.getHeight() + el.getMargins('tb')
			};
	},


	getPosition : function(local){
		var el = this.getPositionEl();
		if(local === true){
			return [el.getLeft(true), el.getTop(true)];
		}
		return this.xy || el.getXY();
	},


	getBox : function(local){
		var pos = this.getPosition(local);
		var s = this.getSize();
		s.x = pos[0];
		s.y = pos[1];
		return s;
	},


	updateBox : function(box){
		this.setSize(box.width, box.height);
		this.setPagePosition(box.x, box.y);
		return this;
	},


	getResizeEl : function(){
		return this.resizeEl || this.el;
	},


	setAutoScroll : function(scroll){
		if(this.rendered){
			this.getContentTarget().setOverflow(scroll ? 'auto' : '');
		}
		this.autoScroll = scroll;
		return this;
	},


	setPosition : function(x, y){
		if(x && typeof x[1] == 'number'){
			y = x[1];
			x = x[0];
		}
		this.x = x;
		this.y = y;
		if(!this.boxReady){
			return this;
		}
		var adj = this.adjustPosition(x, y);
		var ax = adj.x, ay = adj.y;

		var el = this.getPositionEl();
		if(ax !== undefined || ay !== undefined){
			if(ax !== undefined && ay !== undefined){
				el.setLeftTop(ax, ay);
			}else if(ax !== undefined){
				el.setLeft(ax);
			}else if(ay !== undefined){
				el.setTop(ay);
			}
			this.onPosition(ax, ay);
			this.fireEvent('move', this, ax, ay);
		}
		return this;
	},


	setPagePosition : function(x, y){
		if(x && typeof x[1] == 'number'){
			y = x[1];
			x = x[0];
		}
		this.pageX = x;
		this.pageY = y;
		if(!this.boxReady){
			return;
		}
		if(x === undefined || y === undefined){
			return;
		}
		var p = this.getPositionEl().translatePoints(x, y);
		this.setPosition(p.left, p.top);
		return this;
	},


	afterRender : function(){
		Ext.BoxComponent.superclass.afterRender.call(this);
		if(this.resizeEl){
			this.resizeEl = Ext.get(this.resizeEl);
		}
		if(this.positionEl){
			this.positionEl = Ext.get(this.positionEl);
		}
		this.boxReady = true;
		Ext.isDefined(this.autoScroll) && this.setAutoScroll(this.autoScroll);
		this.setSize(this.width, this.height);
		if(this.x || this.y){
			this.setPosition(this.x, this.y);
		}else if(this.pageX || this.pageY){
			this.setPagePosition(this.pageX, this.pageY);
		}
	},


	syncSize : function(){
		delete this.lastSize;
		this.setSize(this.autoWidth ? undefined : this.getResizeEl().getWidth(), this.autoHeight ? undefined : this.getResizeEl().getHeight());
		return this;
	},


	onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
	},


	onPosition : function(x, y){

	},


	adjustSize : function(w, h){
		if(this.autoWidth){
			w = 'auto';
		}
		if(this.autoHeight){
			h = 'auto';
		}
		return {
			width : w,
			height: h
		};
	},


	adjustPosition : function(x, y){
		return {
			x : x,
			y: y
		};
	}
});
Ext.reg('box', Ext.BoxComponent);



Ext.Spacer = Ext.extend(Ext.BoxComponent, {
	autoEl:'div'
});
Ext.reg('spacer', Ext.Spacer);
Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){


	this.el = Ext.get(dragElement, true);
	this.el.dom.unselectable = "on";

	this.resizingEl = Ext.get(resizingElement, true);


	this.orientation = orientation || Ext.SplitBar.HORIZONTAL;



	this.minSize = 0;


	this.maxSize = 2000;


	this.animate = false;


	this.useShim = false;


	this.shim = null;

	if(!existingProxy){

		this.proxy = Ext.SplitBar.createProxy(this.orientation);
	}else{
		this.proxy = Ext.get(existingProxy).dom;
	}

	this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {
		dragElId : this.proxy.id
		});


	this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);


	this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);


	this.dragSpecs = {};


	this.adapter = new Ext.SplitBar.BasicLayoutAdapter();
	this.adapter.init(this);

	if(this.orientation == Ext.SplitBar.HORIZONTAL){

		this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT);
		this.el.addClass("x-splitbar-h");
	}else{

		this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM);
		this.el.addClass("x-splitbar-v");
	}

	this.addEvents(

		"resize",

		"moved",

		"beforeresize",

		"beforeapply"
		);

	Ext.SplitBar.superclass.constructor.call(this);
};

Ext.extend(Ext.SplitBar, Ext.util.Observable, {
	onStartProxyDrag : function(x, y){
		this.fireEvent("beforeresize", this);
		this.overlay =  Ext.DomHelper.append(document.body,  {
			cls: "x-drag-overlay",
			html: "&#160;"
		}, true);
		this.overlay.unselectable();
		this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
		this.overlay.show();
		Ext.get(this.proxy).setDisplayed("block");
		var size = this.adapter.getElementSize(this);
		this.activeMinSize = this.getMinimumSize();
		this.activeMaxSize = this.getMaximumSize();
		var c1 = size - this.activeMinSize;
		var c2 = Math.max(this.activeMaxSize - size, 0);
		if(this.orientation == Ext.SplitBar.HORIZONTAL){
			this.dd.resetConstraints();
			this.dd.setXConstraint(
				this.placement == Ext.SplitBar.LEFT ? c1 : c2,
				this.placement == Ext.SplitBar.LEFT ? c2 : c1,
				this.tickSize
				);
			this.dd.setYConstraint(0, 0);
		}else{
			this.dd.resetConstraints();
			this.dd.setXConstraint(0, 0);
			this.dd.setYConstraint(
				this.placement == Ext.SplitBar.TOP ? c1 : c2,
				this.placement == Ext.SplitBar.TOP ? c2 : c1,
				this.tickSize
				);
		}
		this.dragSpecs.startSize = size;
		this.dragSpecs.startPoint = [x, y];
		Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);
	},


	onEndProxyDrag : function(e){
		Ext.get(this.proxy).setDisplayed(false);
		var endPoint = Ext.lib.Event.getXY(e);
		if(this.overlay){
			Ext.destroy(this.overlay);
			delete this.overlay;
		}
		var newSize;
		if(this.orientation == Ext.SplitBar.HORIZONTAL){
			newSize = this.dragSpecs.startSize +
			(this.placement == Ext.SplitBar.LEFT ?
				endPoint[0] - this.dragSpecs.startPoint[0] :
				this.dragSpecs.startPoint[0] - endPoint[0]
				);
		}else{
			newSize = this.dragSpecs.startSize +
			(this.placement == Ext.SplitBar.TOP ?
				endPoint[1] - this.dragSpecs.startPoint[1] :
				this.dragSpecs.startPoint[1] - endPoint[1]
				);
		}
		newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);
		if(newSize != this.dragSpecs.startSize){
			if(this.fireEvent('beforeapply', this, newSize) !== false){
				this.adapter.setElementSize(this, newSize);
				this.fireEvent("moved", this, newSize);
				this.fireEvent("resize", this, newSize);
			}
		}
	},


	getAdapter : function(){
		return this.adapter;
	},


	setAdapter : function(adapter){
		this.adapter = adapter;
		this.adapter.init(this);
	},


	getMinimumSize : function(){
		return this.minSize;
	},


	setMinimumSize : function(minSize){
		this.minSize = minSize;
	},


	getMaximumSize : function(){
		return this.maxSize;
	},


	setMaximumSize : function(maxSize){
		this.maxSize = maxSize;
	},


	setCurrentSize : function(size){
		var oldAnimate = this.animate;
		this.animate = false;
		this.adapter.setElementSize(this, size);
		this.animate = oldAnimate;
	},


	destroy : function(removeEl){
		Ext.destroy(this.shim, Ext.get(this.proxy));
		this.dd.unreg();
		if(removeEl){
			this.el.remove();
		}
		this.purgeListeners();
	}
});


Ext.SplitBar.createProxy = function(dir){
	var proxy = new Ext.Element(document.createElement("div"));
	document.body.appendChild(proxy.dom);
	proxy.unselectable();
	var cls = 'x-splitbar-proxy';
	proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));
	return proxy.dom;
};


Ext.SplitBar.BasicLayoutAdapter = function(){
	};

Ext.SplitBar.BasicLayoutAdapter.prototype = {

	init : function(s){

	},

	getElementSize : function(s){
		if(s.orientation == Ext.SplitBar.HORIZONTAL){
			return s.resizingEl.getWidth();
		}else{
			return s.resizingEl.getHeight();
		}
	},


	setElementSize : function(s, newSize, onComplete){
		if(s.orientation == Ext.SplitBar.HORIZONTAL){
			if(!s.animate){
				s.resizingEl.setWidth(newSize);
				if(onComplete){
					onComplete(s, newSize);
				}
			}else{
				s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');
			}
		}else{

			if(!s.animate){
				s.resizingEl.setHeight(newSize);
				if(onComplete){
					onComplete(s, newSize);
				}
			}else{
				s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');
			}
		}
	}
};


Ext.SplitBar.AbsoluteLayoutAdapter = function(container){
	this.basic = new Ext.SplitBar.BasicLayoutAdapter();
	this.container = Ext.get(container);
};

Ext.SplitBar.AbsoluteLayoutAdapter.prototype = {
	init : function(s){
		this.basic.init(s);
	},

	getElementSize : function(s){
		return this.basic.getElementSize(s);
	},

	setElementSize : function(s, newSize, onComplete){
		this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));
	},

	moveSplitter : function(s){
		var yes = Ext.SplitBar;
		switch(s.placement){
			case yes.LEFT:
				s.el.setX(s.resizingEl.getRight());
				break;
			case yes.RIGHT:
				s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px");
				break;
			case yes.TOP:
				s.el.setY(s.resizingEl.getBottom());
				break;
			case yes.BOTTOM:
				s.el.setY(s.resizingEl.getTop() - s.el.getHeight());
				break;
		}
	}
};


Ext.SplitBar.VERTICAL = 1;


Ext.SplitBar.HORIZONTAL = 2;


Ext.SplitBar.LEFT = 1;


Ext.SplitBar.RIGHT = 2;


Ext.SplitBar.TOP = 3;


Ext.SplitBar.BOTTOM = 4;

Ext.Container = Ext.extend(Ext.BoxComponent, {




	bufferResize: 50,







	autoDestroy : true,


	forceLayout: false,



	defaultType : 'panel',


	resizeEvent: 'resize',


	bubbleEvents: ['add', 'remove'],


	initComponent : function(){
		Ext.Container.superclass.initComponent.call(this);

		this.addEvents(

			'afterlayout',

			'beforeadd',

			'beforeremove',

			'add',

			'remove'
			);


		var items = this.items;
		if(items){
			delete this.items;
			this.add(items);
		}
	},


	initItems : function(){
		if(!this.items){
			this.items = new Ext.util.MixedCollection(false, this.getComponentId);
			this.getLayout();
		}
	},


	setLayout : function(layout){
		if(this.layout && this.layout != layout){
			this.layout.setContainer(null);
		}
		this.layout = layout;
		this.initItems();
		layout.setContainer(this);
	},

	afterRender: function(){


		Ext.Container.superclass.afterRender.call(this);
		if(!this.layout){
			this.layout = 'auto';
		}
		if(Ext.isObject(this.layout) && !this.layout.layout){
			this.layoutConfig = this.layout;
			this.layout = this.layoutConfig.type;
		}
		if(Ext.isString(this.layout)){
			this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
		}
		this.setLayout(this.layout);


		if(this.activeItem !== undefined && this.layout.setActiveItem){
			var item = this.activeItem;
			delete this.activeItem;
			this.layout.setActiveItem(item);
		}


		if(!this.ownerCt){
			this.doLayout(false, true);
		}



		if(this.monitorResize === true){
			Ext.EventManager.onWindowResize(this.doLayout, this, [false]);
		}
	},


	getLayoutTarget : function(){
		return this.el;
	},


	getComponentId : function(comp){
		return comp.getItemId();
	},


	add : function(comp){
		this.initItems();
		var args = arguments.length > 1;
		if(args || Ext.isArray(comp)){
			var result = [];
			Ext.each(args ? arguments : comp, function(c){
				result.push(this.add(c));
			}, this);
			return result;
		}
		var c = this.lookupComponent(this.applyDefaults(comp));
		var index = this.items.length;
		if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
			this.items.add(c);

			c.onAdded(this, index);
			this.onAdd(c);
			this.fireEvent('add', this, c, index);
		}
		return c;
	},

	onAdd : function(c){

	},


	onAdded : function(container, pos) {

		this.ownerCt = container;
		this.initRef();

		this.cascade(function(c){
			c.initRef();
		});
		this.fireEvent('added', this, container, pos);
	},


	insert : function(index, comp) {
		var args   = arguments,
		length = args.length,
		result = [],
		i, c;

		this.initItems();

		if (length > 2) {
			for (i = length - 1; i >= 1; --i) {
				result.push(this.insert(index, args[i]));
			}
			return result;
		}

		c = this.lookupComponent(this.applyDefaults(comp));
		index = Math.min(index, this.items.length);

		if (this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false) {
			if (c.ownerCt == this) {
				this.items.remove(c);
			}
			this.items.insert(index, c);
			c.onAdded(this, index);
			this.onAdd(c);
			this.fireEvent('add', this, c, index);
		}

		return c;
	},


	applyDefaults : function(c){
		var d = this.defaults;
		if(d){
			if(Ext.isFunction(d)){
				d = d.call(this, c);
			}
			if(Ext.isString(c)){
				c = Ext.ComponentMgr.get(c);
				Ext.apply(c, d);
			}else if(!c.events){
				Ext.applyIf(c.isAction ? c.initialConfig : c, d);
			}else{
				Ext.apply(c, d);
			}
		}
		return c;
	},


	onBeforeAdd : function(item){
		if(item.ownerCt){
			item.ownerCt.remove(item, false);
		}
		if(this.hideBorders === true){
			item.border = (item.border === true);
		}
	},


	remove : function(comp, autoDestroy){
		this.initItems();
		var c = this.getComponent(comp);
		if(c && this.fireEvent('beforeremove', this, c) !== false){
			this.doRemove(c, autoDestroy);
			this.fireEvent('remove', this, c);
		}
		return c;
	},

	onRemove: function(c){

	},


	doRemove: function(c, autoDestroy){
		var l = this.layout,
		hasLayout = l && this.rendered;

		if(hasLayout){
			l.onRemove(c);
		}
		this.items.remove(c);
		c.onRemoved();
		this.onRemove(c);
		if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){
			c.destroy();
		}
		if(hasLayout){
			l.afterRemove(c);
		}
	},


	removeAll: function(autoDestroy){
		this.initItems();
		var item, rem = [], items = [];
		this.items.each(function(i){
			rem.push(i);
		});
		for (var i = 0, len = rem.length; i < len; ++i){
			item = rem[i];
			this.remove(item, autoDestroy);
			if(item.ownerCt !== this){
				items.push(item);
			}
		}
		return items;
	},


	getComponent : function(comp){
		if(Ext.isObject(comp)){
			comp = comp.getItemId();
		}
		return this.items.get(comp);
	},


	lookupComponent : function(comp){
		if(Ext.isString(comp)){
			return Ext.ComponentMgr.get(comp);
		}else if(!comp.events){
			return this.createComponent(comp);
		}
		return comp;
	},


	createComponent : function(config, defaultType){
		if (config.render) {
			return config;
		}


		var c = Ext.create(Ext.apply({
			ownerCt: this
		}, config), defaultType || this.defaultType);
		delete c.initialConfig.ownerCt;
		delete c.ownerCt;
		return c;
	},


	canLayout : function() {
		var el = this.getVisibilityEl();
		return el && el.dom && !el.isStyle("display", "none");
	},



	doLayout : function(shallow, force){
		var rendered = this.rendered,
		forceLayout = force || this.forceLayout;

		if(this.collapsed || !this.canLayout()){
			this.deferLayout = this.deferLayout || !shallow;
			if(!forceLayout){
				return;
			}
			shallow = shallow && !this.deferLayout;
		} else {
			delete this.deferLayout;
		}
		if(rendered && this.layout){
			this.layout.layout();
		}
		if(shallow !== true && this.items){
			var cs = this.items.items;
			for(var i = 0, len = cs.length; i < len; i++){
				var c = cs[i];
				if(c.doLayout){
					c.doLayout(false, forceLayout);
				}
			}
		}
		if(rendered){
			this.onLayout(shallow, forceLayout);
		}

		this.hasLayout = true;
		delete this.forceLayout;
	},

	onLayout : Ext.emptyFn,


	shouldBufferLayout: function(){

		var hl = this.hasLayout;
		if(this.ownerCt){

			return hl ? !this.hasLayoutPending() : false;
		}

		return hl;
	},


	hasLayoutPending: function(){

		var pending = false;
		this.ownerCt.bubble(function(c){
			if(c.layoutPending){
				pending = true;
				return false;
			}
		});
		return pending;
	},

	onShow : function(){

		Ext.Container.superclass.onShow.call(this);

		if(Ext.isDefined(this.deferLayout)){
			delete this.deferLayout;
			this.doLayout(true);
		}
	},


	getLayout : function(){
		if(!this.layout){
			var layout = new Ext.layout.AutoLayout(this.layoutConfig);
			this.setLayout(layout);
		}
		return this.layout;
	},


	beforeDestroy : function(){
		var c;
		if(this.items){
			while(c = this.items.first()){
				this.doRemove(c, true);
			}
		}
		if(this.monitorResize){
			Ext.EventManager.removeResizeListener(this.doLayout, this);
		}
		Ext.destroy(this.layout);
		Ext.Container.superclass.beforeDestroy.call(this);
	},


	cascade : function(fn, scope, args){
		if(fn.apply(scope || this, args || [this]) !== false){
			if(this.items){
				var cs = this.items.items;
				for(var i = 0, len = cs.length; i < len; i++){
					if(cs[i].cascade){
						cs[i].cascade(fn, scope, args);
					}else{
						fn.apply(scope || cs[i], args || [cs[i]]);
					}
				}
			}
		}
		return this;
	},


	findById : function(id){
		var m = null,
		ct = this;
		this.cascade(function(c){
			if(ct != c && c.id === id){
				m = c;
				return false;
			}
		});
		return m;
	},


	findByType : function(xtype, shallow){
		return this.findBy(function(c){
			return c.isXType(xtype, shallow);
		});
	},


	find : function(prop, value){
		return this.findBy(function(c){
			return c[prop] === value;
		});
	},


	findBy : function(fn, scope){
		var m = [], ct = this;
		this.cascade(function(c){
			if(ct != c && fn.call(scope || c, c, ct) === true){
				m.push(c);
			}
		});
		return m;
	},


	get : function(key){
		return this.getComponent(key);
	}
});

Ext.Container.LAYOUTS = {};
Ext.reg('container', Ext.Container);

Ext.layout.ContainerLayout = Ext.extend(Object, {






	monitorResize:false,

	activeItem : null,

	constructor : function(config){
		this.id = Ext.id(null, 'ext-layout-');
		Ext.apply(this, config);
	},

	type: 'container',


	IEMeasureHack : function(target, viewFlag) {
		var tChildren = target.dom.childNodes, tLen = tChildren.length, c, d = [], e, i, ret;
		for (i = 0 ; i < tLen ; i++) {
			c = tChildren[i];
			e = Ext.get(c);
			if (e) {
				d[i] = e.getStyle('display');
				e.setStyle({
					display: 'none'
				});
			}
		}
		ret = target ? target.getViewSize(viewFlag) : {};
		for (i = 0 ; i < tLen ; i++) {
			c = tChildren[i];
			e = Ext.get(c);
			if (e) {
				e.setStyle({
					display: d[i]
					});
			}
		}
		return ret;
	},


	getLayoutTargetSize : Ext.EmptyFn,


	layout : function(){
		var ct = this.container, target = ct.getLayoutTarget();
		if(!(this.hasLayout || Ext.isEmpty(this.targetCls))){
			target.addClass(this.targetCls);
		}
		this.onLayout(ct, target);
		ct.fireEvent('afterlayout', ct, this);
	},


	onLayout : function(ct, target){
		this.renderAll(ct, target);
	},


	isValidParent : function(c, target){
		return target && c.getPositionEl().dom.parentNode == (target.dom || target);
	},


	renderAll : function(ct, target){
		var items = ct.items.items, i, c, len = items.length;
		for(i = 0; i < len; i++) {
			c = items[i];
			if(c && (!c.rendered || !this.isValidParent(c, target))){
				this.renderItem(c, i, target);
			}
		}
	},


	renderItem : function(c, position, target){
		if (c) {
			if (!c.rendered) {
				c.render(target, position);
				this.configureItem(c);
			} else if (!this.isValidParent(c, target)) {
				if (Ext.isNumber(position)) {
					position = target.dom.childNodes[position];
				}

				target.dom.insertBefore(c.getPositionEl().dom, position || null);
				c.container = target;
				this.configureItem(c);
			}
		}
	},



	getRenderedItems: function(ct){
		var t = ct.getLayoutTarget(), cti = ct.items.items, len = cti.length, i, c, items = [];
		for (i = 0; i < len; i++) {
			if((c = cti[i]).rendered && this.isValidParent(c, t) && c.shouldLayout !== false){
				items.push(c);
			}
		};
		return items;
	},


	configureItem: function(c){
		if (this.extraCls) {
			var t = c.getPositionEl ? c.getPositionEl() : c;
			t.addClass(this.extraCls);
		}


		if (c.doLayout && this.forceLayout) {
			c.doLayout();
		}
		if (this.renderHidden && c != this.activeItem) {
			c.hide();
		}
	},

	onRemove: function(c){
		if(this.activeItem == c){
			delete this.activeItem;
		}
		if(c.rendered && this.extraCls){
			var t = c.getPositionEl ? c.getPositionEl() : c;
			t.removeClass(this.extraCls);
		}
	},

	afterRemove: function(c){
		if(c.removeRestore){
			c.removeMode = 'container';
			delete c.removeRestore;
		}
	},


	onResize: function(){
		var ct = this.container,
		b;
		if(ct.collapsed){
			return;
		}
		if(b = ct.bufferResize && ct.shouldBufferLayout()){
			if(!this.resizeTask){
				this.resizeTask = new Ext.util.DelayedTask(this.runLayout, this);
				this.resizeBuffer = Ext.isNumber(b) ? b : 50;
			}
			ct.layoutPending = true;
			this.resizeTask.delay(this.resizeBuffer);
		}else{
			this.runLayout();
		}
	},

	runLayout: function(){
		var ct = this.container;
		this.layout();
		ct.onLayout();
		delete ct.layoutPending;
	},


	setContainer : function(ct){

		if(this.monitorResize && ct != this.container){
			var old = this.container;
			if(old){
				old.un(old.resizeEvent, this.onResize, this);
			}
			if(ct){
				ct.on(ct.resizeEvent, this.onResize, this);
			}
		}
		this.container = ct;
	},


	parseMargins : function(v){
		if (Ext.isNumber(v)) {
			v = v.toString();
		}
		var ms  = v.split(' '),
		len = ms.length;

		if (len == 1) {
			ms[1] = ms[2] = ms[3] = ms[0];
		} else if(len == 2) {
			ms[2] = ms[0];
			ms[3] = ms[1];
		} else if(len == 3) {
			ms[3] = ms[1];
		}

		return {
			top   :parseInt(ms[0], 10) || 0,
			right :parseInt(ms[1], 10) || 0,
			bottom:parseInt(ms[2], 10) || 0,
			left  :parseInt(ms[3], 10) || 0
		};
	},


	fieldTpl: (function() {
		var t = new Ext.Template(
			'<div class="x-form-item {itemCls}" tabIndex="-1">',
			'<label for="{id}" style="{labelStyle}" class="x-form-item-label">{label}{labelSeparator}</label>',
			'<div class="x-form-element" id="x-form-el-{id}" style="{elementStyle}">',
			'</div><div class="{clearCls}"></div>',
			'</div>'
			);
		t.disableFormats = true;
		return t.compile();
	})(),


	destroy : function(){

		if(this.resizeTask && this.resizeTask.cancel){
			this.resizeTask.cancel();
		}
		if(this.container) {
			this.container.un(this.container.resizeEvent, this.onResize, this);
		}
		if(!Ext.isEmpty(this.targetCls)){
			var target = this.container.getLayoutTarget();
			if(target){
				target.removeClass(this.targetCls);
			}
		}
	}
});
Ext.layout.AutoLayout = Ext.extend(Ext.layout.ContainerLayout, {
	type: 'auto',

	monitorResize: true,

	onLayout : function(ct, target){
		Ext.layout.AutoLayout.superclass.onLayout.call(this, ct, target);
		var cs = this.getRenderedItems(ct), len = cs.length, i, c;
		for(i = 0; i < len; i++){
			c = cs[i];
			if (c.doLayout){

				c.doLayout(true);
			}
		}
	}
});

Ext.Container.LAYOUTS['auto'] = Ext.layout.AutoLayout;

Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, {

	monitorResize:true,

	type: 'fit',

	getLayoutTargetSize : function() {
		var target = this.container.getLayoutTarget();
		if (!target) {
			return {};
		}

		return target.getStyleSize();
	},


	onLayout : function(ct, target){
		Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target);
		if(!ct.collapsed){
			this.setItemSize(this.activeItem || ct.items.itemAt(0), this.getLayoutTargetSize());
		}
	},


	setItemSize : function(item, size){
		if(item && size.height > 0){
			item.setSize(size);
		}
	}
});
Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout;
Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, {

	deferredRender : false,


	layoutOnCardChange : false,



	renderHidden : true,

	type: 'card',


	setActiveItem : function(item){
		var ai = this.activeItem,
		ct = this.container;
		item = ct.getComponent(item);


		if(item && ai != item){


			if(ai){
				ai.hide();
				if (ai.hidden !== true) {
					return false;
				}
				ai.fireEvent('deactivate', ai);
			}

			var layout = item.doLayout && (this.layoutOnCardChange || !item.rendered);


			this.activeItem = item;



			delete item.deferLayout;


			item.show();

			this.layout();

			if(layout){
				item.doLayout();
			}
			item.fireEvent('activate', item);
		}
	},


	renderAll : function(ct, target){
		if(this.deferredRender){
			this.renderItem(this.activeItem, undefined, target);
		}else{
			Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target);
		}
	}
});
Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout;

Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, {



	monitorResize : true,

	type : 'anchor',


	defaultAnchor : '100%',

	parseAnchorRE : /^(r|right|b|bottom)$/i,


	getLayoutTargetSize : function() {
		var target = this.container.getLayoutTarget(), ret = {};
		if (target) {
			ret = target.getViewSize();




			if (Ext.isIE && Ext.isStrict && ret.width == 0){
				ret =  target.getStyleSize();
			}
			ret.width -= target.getPadding('lr');
			ret.height -= target.getPadding('tb');
		}
		return ret;
	},


	onLayout : function(container, target) {
		Ext.layout.AnchorLayout.superclass.onLayout.call(this, container, target);

		var size = this.getLayoutTargetSize(),
		containerWidth = size.width,
		containerHeight = size.height,
		overflow = target.getStyle('overflow'),
		components = this.getRenderedItems(container),
		len = components.length,
		boxes = [],
		box,
		anchorWidth,
		anchorHeight,
		component,
		anchorSpec,
		calcWidth,
		calcHeight,
		anchorsArray,
		totalHeight = 0,
		i,
		el;

		if(containerWidth < 20 && containerHeight < 20){
			return;
		}


		if(container.anchorSize) {
			if(typeof container.anchorSize == 'number') {
				anchorWidth = container.anchorSize;
			} else {
				anchorWidth = container.anchorSize.width;
				anchorHeight = container.anchorSize.height;
			}
		} else {
			anchorWidth = container.initialConfig.width;
			anchorHeight = container.initialConfig.height;
		}

		for(i = 0; i < len; i++) {
			component = components[i];
			el = component.getPositionEl();


			if (!component.anchor && component.items && !Ext.isNumber(component.width) && !(Ext.isIE6 && Ext.isStrict)){
				component.anchor = this.defaultAnchor;
			}

			if(component.anchor) {
				anchorSpec = component.anchorSpec;

				if(!anchorSpec){
					anchorsArray = component.anchor.split(' ');
					component.anchorSpec = anchorSpec = {
						right: this.parseAnchor(anchorsArray[0], component.initialConfig.width, anchorWidth),
						bottom: this.parseAnchor(anchorsArray[1], component.initialConfig.height, anchorHeight)
					};
				}
				calcWidth = anchorSpec.right ? this.adjustWidthAnchor(anchorSpec.right(containerWidth) - el.getMargins('lr'), component) : undefined;
				calcHeight = anchorSpec.bottom ? this.adjustHeightAnchor(anchorSpec.bottom(containerHeight) - el.getMargins('tb'), component) : undefined;

				if(calcWidth || calcHeight) {
					boxes.push({
						component: component,
						width: calcWidth || undefined,
						height: calcHeight || undefined
					});
				}
			}
		}
		for (i = 0, len = boxes.length; i < len; i++) {
			box = boxes[i];
			box.component.setSize(box.width, box.height);
		}

		if (overflow && overflow != 'hidden' && !this.adjustmentPass) {
			var newTargetSize = this.getLayoutTargetSize();
			if (newTargetSize.width != size.width || newTargetSize.height != size.height){
				this.adjustmentPass = true;
				this.onLayout(container, target);
			}
		}

		delete this.adjustmentPass;
	},


	parseAnchor : function(a, start, cstart) {
		if (a && a != 'none') {
			var last;

			if (this.parseAnchorRE.test(a)) {
				var diff = cstart - start;
				return function(v){
					if(v !== last){
						last = v;
						return v - diff;
					}
				};

			} else if(a.indexOf('%') != -1) {
				var ratio = parseFloat(a.replace('%', ''))*.01;
				return function(v){
					if(v !== last){
						last = v;
						return Math.floor(v*ratio);
					}
				};

			} else {
				a = parseInt(a, 10);
				if (!isNaN(a)) {
					return function(v) {
						if (v !== last) {
							last = v;
							return v + a;
						}
					};
				}
			}
		}
		return false;
	},


	adjustWidthAnchor : function(value, comp){
		return value;
	},


	adjustHeightAnchor : function(value, comp){
		return value;
	}


});
Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout;

Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, {

	monitorResize:true,

	type: 'column',

	extraCls: 'x-column',

	scrollOffset : 0,



	targetCls: 'x-column-layout-ct',

	isValidParent : function(c, target){
		return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom;
	},

	getLayoutTargetSize : function() {
		var target = this.container.getLayoutTarget(), ret;
		if (target) {
			ret = target.getViewSize();




			if (Ext.isIE && Ext.isStrict && ret.width == 0){
				ret =  target.getStyleSize();
			}

			ret.width -= target.getPadding('lr');
			ret.height -= target.getPadding('tb');
		}
		return ret;
	},

	renderAll : function(ct, target) {
		if(!this.innerCt){


			this.innerCt = target.createChild({
				cls:'x-column-inner'
			});
			this.innerCt.createChild({
				cls:'x-clear'
			});
		}
		Ext.layout.ColumnLayout.superclass.renderAll.call(this, ct, this.innerCt);
	},


	onLayout : function(ct, target){
		var cs = ct.items.items,
		len = cs.length,
		c,
		i,
		m,
		margins = [];

		this.renderAll(ct, target);

		var size = this.getLayoutTargetSize();

		if(size.width < 1 && size.height < 1){
			return;
		}

		var w = size.width - this.scrollOffset,
		h = size.height,
		pw = w;

		this.innerCt.setWidth(w);




		for(i = 0; i < len; i++){
			c = cs[i];
			m = c.getPositionEl().getMargins('lr');
			margins[i] = m;
			if(!c.columnWidth){
				pw -= (c.getWidth() + m);
			}
		}

		pw = pw < 0 ? 0 : pw;

		for(i = 0; i < len; i++){
			c = cs[i];
			m = margins[i];
			if(c.columnWidth){
				c.setSize(Math.floor(c.columnWidth * pw) - m);
			}
		}



		if (Ext.isIE) {
			if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) {
				var ts = this.getLayoutTargetSize();
				if (ts.width != size.width){
					this.adjustmentPass = true;
					this.onLayout(ct, target);
				}
			}
		}
		delete this.adjustmentPass;
	}


});

Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout;

Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, {

	monitorResize:true,

	rendered : false,

	type: 'border',

	targetCls: 'x-border-layout-ct',

	getLayoutTargetSize : function() {
		var target = this.container.getLayoutTarget();
		return target ? target.getViewSize() : {};
	},


	onLayout : function(ct, target){
		var collapsed, i, c, pos, items = ct.items.items, len = items.length;
		if(!this.rendered){
			collapsed = [];
			for(i = 0; i < len; i++) {
				c = items[i];
				pos = c.region;
				if(c.collapsed){
					collapsed.push(c);
				}
				c.collapsed = false;
				if(!c.rendered){
					c.render(target, i);
					c.getPositionEl().addClass('x-border-panel');
				}
				this[pos] = pos != 'center' && c.split ?
				new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
				new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos);
				this[pos].render(target, c);
			}
			this.rendered = true;
		}

		var size = this.getLayoutTargetSize();
		if(size.width < 20 || size.height < 20){
			if(collapsed){
				this.restoreCollapsed = collapsed;
			}
			return;
		}else if(this.restoreCollapsed){
			collapsed = this.restoreCollapsed;
			delete this.restoreCollapsed;
		}

		var w = size.width, h = size.height,
		centerW = w, centerH = h, centerY = 0, centerX = 0,
		n = this.north, s = this.south, west = this.west, e = this.east, c = this.center,
		b, m, totalWidth, totalHeight;
		if(!c && Ext.layout.BorderLayout.WARN !== false){
			throw 'No center region defined in BorderLayout ' + ct.id;
		}

		if(n && n.isVisible()){
			b = n.getSize();
			m = n.getMargins();
			b.width = w - (m.left+m.right);
			b.x = m.left;
			b.y = m.top;
			centerY = b.height + b.y + m.bottom;
			centerH -= centerY;
			n.applyLayout(b);
		}
		if(s && s.isVisible()){
			b = s.getSize();
			m = s.getMargins();
			b.width = w - (m.left+m.right);
			b.x = m.left;
			totalHeight = (b.height + m.top + m.bottom);
			b.y = h - totalHeight + m.top;
			centerH -= totalHeight;
			s.applyLayout(b);
		}
		if(west && west.isVisible()){
			b = west.getSize();
			m = west.getMargins();
			b.height = centerH - (m.top+m.bottom);
			b.x = m.left;
			b.y = centerY + m.top;
			totalWidth = (b.width + m.left + m.right);
			centerX += totalWidth;
			centerW -= totalWidth;
			west.applyLayout(b);
		}
		if(e && e.isVisible()){
			b = e.getSize();
			m = e.getMargins();
			b.height = centerH - (m.top+m.bottom);
			totalWidth = (b.width + m.left + m.right);
			b.x = w - totalWidth + m.left;
			b.y = centerY + m.top;
			centerW -= totalWidth;
			e.applyLayout(b);
		}
		if(c){
			m = c.getMargins();
			var centerBox = {
				x: centerX + m.left,
				y: centerY + m.top,
				width: centerW - (m.left+m.right),
				height: centerH - (m.top+m.bottom)
			};
			c.applyLayout(centerBox);
		}
		if(collapsed){
			for(i = 0, len = collapsed.length; i < len; i++){
				collapsed[i].collapse(false);
			}
		}
		if(Ext.isIE && Ext.isStrict){
			target.repaint();
		}

		if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) {
			var ts = this.getLayoutTargetSize();
			if (ts.width != size.width || ts.height != size.height){
				this.adjustmentPass = true;
				this.onLayout(ct, target);
			}
		}
		delete this.adjustmentPass;
	},

	destroy: function() {
		var r = ['north', 'south', 'east', 'west'], i, region;
		for (i = 0; i < r.length; i++) {
			region = this[r[i]];
			if(region){
				if(region.destroy){
					region.destroy();
				}else if (region.split){
					region.split.destroy(true);
				}
			}
		}
		Ext.layout.BorderLayout.superclass.destroy.call(this);
	}


});


Ext.layout.BorderLayout.Region = function(layout, config, pos){
	Ext.apply(this, config);
	this.layout = layout;
	this.position = pos;
	this.state = {};
	if(typeof this.margins == 'string'){
		this.margins = this.layout.parseMargins(this.margins);
	}
	this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins);
	if(this.collapsible){
		if(typeof this.cmargins == 'string'){
			this.cmargins = this.layout.parseMargins(this.cmargins);
		}
		if(this.collapseMode == 'mini' && !this.cmargins){
			this.cmargins = {
				left:0,
				top:0,
				right:0,
				bottom:0
			};
		}else{
			this.cmargins = Ext.applyIf(this.cmargins || {},
				pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins);
		}
	}
};

Ext.layout.BorderLayout.Region.prototype = {






	collapsible : false,

	split:false,

	floatable: true,

	minWidth:50,

	minHeight:50,


	defaultMargins : {
		left:0,
		top:0,
		right:0,
		bottom:0
	},

	defaultNSCMargins : {
		left:5,
		top:5,
		right:5,
		bottom:5
	},

	defaultEWCMargins : {
		left:5,
		top:0,
		right:5,
		bottom:0
	},
	floatingZIndex: 100,


	isCollapsed : false,






	render : function(ct, p){
		this.panel = p;
		p.el.enableDisplayMode();
		this.targetEl = ct;
		this.el = p.el;

		var gs = p.getState, ps = this.position;
		p.getState = function(){
			return Ext.apply(gs.call(p) || {}, this.state);
		}.createDelegate(this);

		if(ps != 'center'){
			p.allowQueuedExpand = false;
			p.on({
				beforecollapse: this.beforeCollapse,
				collapse: this.onCollapse,
				beforeexpand: this.beforeExpand,
				expand: this.onExpand,
				hide: this.onHide,
				show: this.onShow,
				scope: this
			});
			if(this.collapsible || this.floatable){
				p.collapseEl = 'el';
				p.slideAnchor = this.getSlideAnchor();
			}
			if(p.tools && p.tools.toggle){
				p.tools.toggle.addClass('x-tool-collapse-'+ps);
				p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over');
			}
		}
	},


	getCollapsedEl : function(){
		if(!this.collapsedEl){
			if(!this.toolTemplate){
				var tt = new Ext.Template(
					'<div class="x-tool x-tool-{id}">&#160;</div>'
					);
				tt.disableFormats = true;
				tt.compile();
				Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt;
			}
			this.collapsedEl = this.targetEl.createChild({
				cls: "x-layout-collapsed x-layout-collapsed-"+this.position,
				id: this.panel.id + '-xcollapsed'
			});
			this.collapsedEl.enableDisplayMode('block');

			if(this.collapseMode == 'mini'){
				this.collapsedEl.addClass('x-layout-cmini-'+this.position);
				this.miniCollapsedEl = this.collapsedEl.createChild({
					cls: "x-layout-mini x-layout-mini-"+this.position,
					html: "&#160;"
				});
				this.miniCollapsedEl.addClassOnOver('x-layout-mini-over');
				this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
				this.collapsedEl.on('click', this.onExpandClick, this, {
					stopEvent:true
				});
			}else {
				if(this.collapsible !== false && !this.hideCollapseTool) {
					var t = this.expandToolEl = this.toolTemplate.append(
						this.collapsedEl.dom,
						{
							id:'expand-'+this.position
							}, true);
					t.addClassOnOver('x-tool-expand-'+this.position+'-over');
					t.on('click', this.onExpandClick, this, {
						stopEvent:true
					});
				}
				if(this.floatable !== false || this.titleCollapse){
					this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
					this.collapsedEl.on("click", this[this.floatable ? 'collapseClick' : 'onExpandClick'], this);
				}
			}
		}
		return this.collapsedEl;
	},


	onExpandClick : function(e){
		if(this.isSlid){
			this.panel.expand(false);
		}else{
			this.panel.expand();
		}
	},


	onCollapseClick : function(e){
		this.panel.collapse();
	},


	beforeCollapse : function(p, animate){
		this.lastAnim = animate;
		if(this.splitEl){
			this.splitEl.hide();
		}
		this.getCollapsedEl().show();
		var el = this.panel.getEl();
		this.originalZIndex = el.getStyle('z-index');
		el.setStyle('z-index', 100);
		this.isCollapsed = true;
		this.layout.layout();
	},


	onCollapse : function(animate){
		this.panel.el.setStyle('z-index', 1);
		if(this.lastAnim === false || this.panel.animCollapse === false){
			this.getCollapsedEl().dom.style.visibility = 'visible';
		}else{
			this.getCollapsedEl().slideIn(this.panel.slideAnchor, {
				duration:.2
			});
		}
		this.state.collapsed = true;
		this.panel.saveState();
	},


	beforeExpand : function(animate){
		if(this.isSlid){
			this.afterSlideIn();
		}
		var c = this.getCollapsedEl();
		this.el.show();
		if(this.position == 'east' || this.position == 'west'){
			this.panel.setSize(undefined, c.getHeight());
		}else{
			this.panel.setSize(c.getWidth(), undefined);
		}
		c.hide();
		c.dom.style.visibility = 'hidden';
		this.panel.el.setStyle('z-index', this.floatingZIndex);
	},


	onExpand : function(){
		this.isCollapsed = false;
		if(this.splitEl){
			this.splitEl.show();
		}
		this.layout.layout();
		this.panel.el.setStyle('z-index', this.originalZIndex);
		this.state.collapsed = false;
		this.panel.saveState();
	},


	collapseClick : function(e){
		if(this.isSlid){
			e.stopPropagation();
			this.slideIn();
		}else{
			e.stopPropagation();
			this.slideOut();
		}
	},


	onHide : function(){
		if(this.isCollapsed){
			this.getCollapsedEl().hide();
		}else if(this.splitEl){
			this.splitEl.hide();
		}
	},


	onShow : function(){
		if(this.isCollapsed){
			this.getCollapsedEl().show();
		}else if(this.splitEl){
			this.splitEl.show();
		}
	},


	isVisible : function(){
		return !this.panel.hidden;
	},


	getMargins : function(){
		return this.isCollapsed && this.cmargins ? this.cmargins : this.margins;
	},


	getSize : function(){
		return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize();
	},


	setPanel : function(panel){
		this.panel = panel;
	},


	getMinWidth: function(){
		return this.minWidth;
	},


	getMinHeight: function(){
		return this.minHeight;
	},


	applyLayoutCollapsed : function(box){
		var ce = this.getCollapsedEl();
		ce.setLeftTop(box.x, box.y);
		ce.setSize(box.width, box.height);
	},


	applyLayout : function(box){
		if(this.isCollapsed){
			this.applyLayoutCollapsed(box);
		}else{
			this.panel.setPosition(box.x, box.y);
			this.panel.setSize(box.width, box.height);
		}
	},


	beforeSlide: function(){
		this.panel.beforeEffect();
	},


	afterSlide : function(){
		this.panel.afterEffect();
	},


	initAutoHide : function(){
		if(this.autoHide !== false){
			if(!this.autoHideHd){
				this.autoHideSlideTask = new Ext.util.DelayedTask(this.slideIn, this);
				this.autoHideHd = {
					"mouseout": function(e){
						if(!e.within(this.el, true)){
							this.autoHideSlideTask.delay(500);
						}
					},
					"mouseover" : function(e){
						this.autoHideSlideTask.cancel();
					},
					scope : this
				};
			}
			this.el.on(this.autoHideHd);
			this.collapsedEl.on(this.autoHideHd);
		}
	},


	clearAutoHide : function(){
		if(this.autoHide !== false){
			this.el.un("mouseout", this.autoHideHd.mouseout);
			this.el.un("mouseover", this.autoHideHd.mouseover);
			this.collapsedEl.un("mouseout", this.autoHideHd.mouseout);
			this.collapsedEl.un("mouseover", this.autoHideHd.mouseover);
		}
	},


	clearMonitor : function(){
		Ext.getDoc().un("click", this.slideInIf, this);
	},


	slideOut : function(){
		if(this.isSlid || this.el.hasActiveFx()){
			return;
		}
		this.isSlid = true;
		var ts = this.panel.tools, dh, pc;
		if(ts && ts.toggle){
			ts.toggle.hide();
		}
		this.el.show();


		pc = this.panel.collapsed;
		this.panel.collapsed = false;

		if(this.position == 'east' || this.position == 'west'){

			dh = this.panel.deferHeight;
			this.panel.deferHeight = false;

			this.panel.setSize(undefined, this.collapsedEl.getHeight());


			this.panel.deferHeight = dh;
		}else{
			this.panel.setSize(this.collapsedEl.getWidth(), undefined);
		}


		this.panel.collapsed = pc;

		this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top];
		this.el.alignTo(this.collapsedEl, this.getCollapseAnchor());
		this.el.setStyle("z-index", this.floatingZIndex+2);
		this.panel.el.replaceClass('x-panel-collapsed', 'x-panel-floating');
		if(this.animFloat !== false){
			this.beforeSlide();
			this.el.slideIn(this.getSlideAnchor(), {
				callback: function(){
					this.afterSlide();
					this.initAutoHide();
					Ext.getDoc().on("click", this.slideInIf, this);
				},
				scope: this,
				block: true
			});
		}else{
			this.initAutoHide();
			Ext.getDoc().on("click", this.slideInIf, this);
		}
	},


	afterSlideIn : function(){
		this.clearAutoHide();
		this.isSlid = false;
		this.clearMonitor();
		this.el.setStyle("z-index", "");
		this.panel.el.replaceClass('x-panel-floating', 'x-panel-collapsed');
		this.el.dom.style.left = this.restoreLT[0];
		this.el.dom.style.top = this.restoreLT[1];

		var ts = this.panel.tools;
		if(ts && ts.toggle){
			ts.toggle.show();
		}
	},


	slideIn : function(cb){
		if(!this.isSlid || this.el.hasActiveFx()){
			Ext.callback(cb);
			return;
		}
		this.isSlid = false;
		if(this.animFloat !== false){
			this.beforeSlide();
			this.el.slideOut(this.getSlideAnchor(), {
				callback: function(){
					this.el.hide();
					this.afterSlide();
					this.afterSlideIn();
					Ext.callback(cb);
				},
				scope: this,
				block: true
			});
		}else{
			this.el.hide();
			this.afterSlideIn();
		}
	},


	slideInIf : function(e){
		if(!e.within(this.el)){
			this.slideIn();
		}
	},


	anchors : {
		"west" : "left",
		"east" : "right",
		"north" : "top",
		"south" : "bottom"
	},


	sanchors : {
		"west" : "l",
		"east" : "r",
		"north" : "t",
		"south" : "b"
	},


	canchors : {
		"west" : "tl-tr",
		"east" : "tr-tl",
		"north" : "tl-bl",
		"south" : "bl-tl"
	},


	getAnchor : function(){
		return this.anchors[this.position];
	},


	getCollapseAnchor : function(){
		return this.canchors[this.position];
	},


	getSlideAnchor : function(){
		return this.sanchors[this.position];
	},


	getAlignAdj : function(){
		var cm = this.cmargins;
		switch(this.position){
			case "west":
				return [0, 0];
				break;
			case "east":
				return [0, 0];
				break;
			case "north":
				return [0, 0];
				break;
			case "south":
				return [0, 0];
				break;
		}
	},


	getExpandAdj : function(){
		var c = this.collapsedEl, cm = this.cmargins;
		switch(this.position){
			case "west":
				return [-(cm.right+c.getWidth()+cm.left), 0];
				break;
			case "east":
				return [cm.right+c.getWidth()+cm.left, 0];
				break;
			case "north":
				return [0, -(cm.top+cm.bottom+c.getHeight())];
				break;
			case "south":
				return [0, cm.top+cm.bottom+c.getHeight()];
				break;
		}
	},

	destroy : function(){
		if (this.autoHideSlideTask && this.autoHideSlideTask.cancel){
			this.autoHideSlideTask.cancel();
		}
		Ext.destroyMembers(this, 'miniCollapsedEl', 'collapsedEl', 'expandToolEl');
	}
};


Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){
	Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos);

	this.applyLayout = this.applyFns[pos];
};

Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, {


	splitTip : "Drag to resize.",

	collapsibleSplitTip : "Drag to resize. Double click to hide.",

	useSplitTips : false,


	splitSettings : {
		north : {
			orientation: Ext.SplitBar.VERTICAL,
			placement: Ext.SplitBar.TOP,
			maxFn : 'getVMaxSize',
			minProp: 'minHeight',
			maxProp: 'maxHeight'
		},
		south : {
			orientation: Ext.SplitBar.VERTICAL,
			placement: Ext.SplitBar.BOTTOM,
			maxFn : 'getVMaxSize',
			minProp: 'minHeight',
			maxProp: 'maxHeight'
		},
		east : {
			orientation: Ext.SplitBar.HORIZONTAL,
			placement: Ext.SplitBar.RIGHT,
			maxFn : 'getHMaxSize',
			minProp: 'minWidth',
			maxProp: 'maxWidth'
		},
		west : {
			orientation: Ext.SplitBar.HORIZONTAL,
			placement: Ext.SplitBar.LEFT,
			maxFn : 'getHMaxSize',
			minProp: 'minWidth',
			maxProp: 'maxWidth'
		}
	},


	applyFns : {
		west : function(box){
			if(this.isCollapsed){
				return this.applyLayoutCollapsed(box);
			}
			var sd = this.splitEl.dom, s = sd.style;
			this.panel.setPosition(box.x, box.y);
			var sw = sd.offsetWidth;
			s.left = (box.x+box.width-sw)+'px';
			s.top = (box.y)+'px';
			s.height = Math.max(0, box.height)+'px';
			this.panel.setSize(box.width-sw, box.height);
		},
		east : function(box){
			if(this.isCollapsed){
				return this.applyLayoutCollapsed(box);
			}
			var sd = this.splitEl.dom, s = sd.style;
			var sw = sd.offsetWidth;
			this.panel.setPosition(box.x+sw, box.y);
			s.left = (box.x)+'px';
			s.top = (box.y)+'px';
			s.height = Math.max(0, box.height)+'px';
			this.panel.setSize(box.width-sw, box.height);
		},
		north : function(box){
			if(this.isCollapsed){
				return this.applyLayoutCollapsed(box);
			}
			var sd = this.splitEl.dom, s = sd.style;
			var sh = sd.offsetHeight;
			this.panel.setPosition(box.x, box.y);
			s.left = (box.x)+'px';
			s.top = (box.y+box.height-sh)+'px';
			s.width = Math.max(0, box.width)+'px';
			this.panel.setSize(box.width, box.height-sh);
		},
		south : function(box){
			if(this.isCollapsed){
				return this.applyLayoutCollapsed(box);
			}
			var sd = this.splitEl.dom, s = sd.style;
			var sh = sd.offsetHeight;
			this.panel.setPosition(box.x, box.y+sh);
			s.left = (box.x)+'px';
			s.top = (box.y)+'px';
			s.width = Math.max(0, box.width)+'px';
			this.panel.setSize(box.width, box.height-sh);
		}
	},


	render : function(ct, p){
		Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p);

		var ps = this.position;

		this.splitEl = ct.createChild({
			cls: "x-layout-split x-layout-split-"+ps,
			html: "&#160;",
			id: this.panel.id + '-xsplit'
		});

		if(this.collapseMode == 'mini'){
			this.miniSplitEl = this.splitEl.createChild({
				cls: "x-layout-mini x-layout-mini-"+ps,
				html: "&#160;"
			});
			this.miniSplitEl.addClassOnOver('x-layout-mini-over');
			this.miniSplitEl.on('click', this.onCollapseClick, this, {
				stopEvent:true
			});
		}

		var s = this.splitSettings[ps];

		this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation);
		this.split.tickSize = this.tickSize;
		this.split.placement = s.placement;
		this.split.getMaximumSize = this[s.maxFn].createDelegate(this);
		this.split.minSize = this.minSize || this[s.minProp];
		this.split.on("beforeapply", this.onSplitMove, this);
		this.split.useShim = this.useShim === true;
		this.maxSize = this.maxSize || this[s.maxProp];

		if(p.hidden){
			this.splitEl.hide();
		}

		if(this.useSplitTips){
			this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip;
		}
		if(this.collapsible){
			this.splitEl.on("dblclick", this.onCollapseClick,  this);
		}
	},


	getSize : function(){
		if(this.isCollapsed){
			return this.collapsedEl.getSize();
		}
		var s = this.panel.getSize();
		if(this.position == 'north' || this.position == 'south'){
			s.height += this.splitEl.dom.offsetHeight;
		}else{
			s.width += this.splitEl.dom.offsetWidth;
		}
		return s;
	},


	getHMaxSize : function(){
		var cmax = this.maxSize || 10000;
		var center = this.layout.center;
		return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth());
	},


	getVMaxSize : function(){
		var cmax = this.maxSize || 10000;
		var center = this.layout.center;
		return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight());
	},


	onSplitMove : function(split, newSize){
		var s = this.panel.getSize();
		this.lastSplitSize = newSize;
		if(this.position == 'north' || this.position == 'south'){
			this.panel.setSize(s.width, newSize);
			this.state.height = newSize;
		}else{
			this.panel.setSize(newSize, s.height);
			this.state.width = newSize;
		}
		this.layout.layout();
		this.panel.saveState();
		return false;
	},


	getSplitBar : function(){
		return this.split;
	},


	destroy : function() {
		Ext.destroy(this.miniSplitEl, this.split, this.splitEl);
		Ext.layout.BorderLayout.SplitRegion.superclass.destroy.call(this);
	}
});

Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout;

Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, {


	labelSeparator : ':',




	trackLabels: true,

	type: 'form',

	onRemove: function(c){
		Ext.layout.FormLayout.superclass.onRemove.call(this, c);
		if(this.trackLabels){
			c.un('show', this.onFieldShow, this);
			c.un('hide', this.onFieldHide, this);
		}

		var el = c.getPositionEl(),
		ct = c.getItemCt && c.getItemCt();
		if (c.rendered && ct) {
			if (el && el.dom) {
				el.insertAfter(ct);
			}
			Ext.destroy(ct);
			Ext.destroyMembers(c, 'label', 'itemCt');
			if (c.customItemCt) {
				Ext.destroyMembers(c, 'getItemCt', 'customItemCt');
			}
		}
	},


	setContainer : function(ct){
		Ext.layout.FormLayout.superclass.setContainer.call(this, ct);
		if(ct.labelAlign){
			ct.addClass('x-form-label-'+ct.labelAlign);
		}

		if(ct.hideLabels){
			Ext.apply(this, {
				labelStyle: 'display:none',
				elementStyle: 'padding-left:0;',
				labelAdjust: 0
			});
		}else{
			this.labelSeparator = Ext.isDefined(ct.labelSeparator) ? ct.labelSeparator : this.labelSeparator;
			ct.labelWidth = ct.labelWidth || 100;
			if(Ext.isNumber(ct.labelWidth)){
				var pad = Ext.isNumber(ct.labelPad) ? ct.labelPad : 5;
				Ext.apply(this, {
					labelAdjust: ct.labelWidth + pad,
					labelStyle: 'width:' + ct.labelWidth + 'px;',
					elementStyle: 'padding-left:' + (ct.labelWidth + pad) + 'px'
				});
			}
			if(ct.labelAlign == 'top'){
				Ext.apply(this, {
					labelStyle: 'width:auto;',
					labelAdjust: 0,
					elementStyle: 'padding-left:0;'
				});
			}
		}
	},


	isHide: function(c){
		return c.hideLabel || this.container.hideLabels;
	},

	onFieldShow: function(c){
		c.getItemCt().removeClass('x-hide-' + c.hideMode);


		if (c.isComposite) {
			c.doLayout();
		}
	},

	onFieldHide: function(c){
		c.getItemCt().addClass('x-hide-' + c.hideMode);
	},


	getLabelStyle: function(s){
		var ls = '', items = [this.labelStyle, s];
		for (var i = 0, len = items.length; i < len; ++i){
			if (items[i]){
				ls += items[i];
				if (ls.substr(-1, 1) != ';'){
					ls += ';';
				}
			}
		}
		return ls;
	},




	renderItem : function(c, position, target){
		if(c && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){
			var args = this.getTemplateArgs(c);
			if(Ext.isNumber(position)){
				position = target.dom.childNodes[position] || null;
			}
			if(position){
				c.itemCt = this.fieldTpl.insertBefore(position, args, true);
			}else{
				c.itemCt = this.fieldTpl.append(target, args, true);
			}
			if(!c.getItemCt){


				Ext.apply(c, {
					getItemCt: function(){
						return c.itemCt;
					},
					customItemCt: true
				});
			}
			c.label = c.getItemCt().child('label.x-form-item-label');
			if(!c.rendered){
				c.render('x-form-el-' + c.id);
			}else if(!this.isValidParent(c, target)){
				Ext.fly('x-form-el-' + c.id).appendChild(c.getPositionEl());
			}
			if(this.trackLabels){
				if(c.hidden){
					this.onFieldHide(c);
				}
				c.on({
					scope: this,
					show: this.onFieldShow,
					hide: this.onFieldHide
				});
			}
			this.configureItem(c);
		}else {
			Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
		}
	},


	getTemplateArgs: function(field) {
		var noLabelSep = !field.fieldLabel || field.hideLabel;

		return {
			id            : field.id,
			label         : field.fieldLabel,
			itemCls       : (field.itemCls || this.container.itemCls || '') + (field.hideLabel ? ' x-hide-label' : ''),
			clearCls      : field.clearCls || 'x-form-clear-left',
			labelStyle    : this.getLabelStyle(field.labelStyle),
			elementStyle  : this.elementStyle || '',
			labelSeparator: noLabelSep ? '' : (Ext.isDefined(field.labelSeparator) ? field.labelSeparator : this.labelSeparator)
		};
	},


	adjustWidthAnchor: function(value, c){
		if(c.label && !this.isHide(c) && (this.container.labelAlign != 'top')){
			var adjust = Ext.isIE6 || (Ext.isIE && !Ext.isStrict);
			return value - this.labelAdjust + (adjust ? -3 : 0);
		}
		return value;
	},

	adjustHeightAnchor : function(value, c){
		if(c.label && !this.isHide(c) && (this.container.labelAlign == 'top')){
			return value - c.label.getHeight();
		}
		return value;
	},


	isValidParent : function(c, target){
		return target && this.container.getEl().contains(c.getPositionEl());
	}


});

Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout;

Ext.layout.AccordionLayout = Ext.extend(Ext.layout.FitLayout, {

	fill : true,

	autoWidth : true,

	titleCollapse : true,

	hideCollapseTool : false,

	collapseFirst : false,

	animate : false,

	sequence : false,

	activeOnTop : false,

	type: 'accordion',

	renderItem : function(c){
		if(this.animate === false){
			c.animCollapse = false;
		}
		c.collapsible = true;
		if(this.autoWidth){
			c.autoWidth = true;
		}
		if(this.titleCollapse){
			c.titleCollapse = true;
		}
		if(this.hideCollapseTool){
			c.hideCollapseTool = true;
		}
		if(this.collapseFirst !== undefined){
			c.collapseFirst = this.collapseFirst;
		}
		if(!this.activeItem && !c.collapsed){
			this.setActiveItem(c, true);
		}else if(this.activeItem && this.activeItem != c){
			c.collapsed = true;
		}
		Ext.layout.AccordionLayout.superclass.renderItem.apply(this, arguments);
		c.header.addClass('x-accordion-hd');
		c.on('beforeexpand', this.beforeExpand, this);
	},

	onRemove: function(c){
		Ext.layout.AccordionLayout.superclass.onRemove.call(this, c);
		if(c.rendered){
			c.header.removeClass('x-accordion-hd');
		}
		c.un('beforeexpand', this.beforeExpand, this);
	},


	beforeExpand : function(p, anim){
		var ai = this.activeItem;
		if(ai){
			if(this.sequence){
				delete this.activeItem;
				if (!ai.collapsed){
					ai.collapse({
						callback:function(){
							p.expand(anim || true);
						},
						scope: this
					});
					return false;
				}
			}else{
				ai.collapse(this.animate);
			}
		}
		this.setActive(p);
		if(this.activeOnTop){
			p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild);
		}

		this.layout();
	},


	setItemSize : function(item, size){
		if(this.fill && item){
			var hh = 0, i, ct = this.getRenderedItems(this.container), len = ct.length, p;

			for (i = 0; i < len; i++) {
				if((p = ct[i]) != item && !p.hidden){
					hh += p.header.getHeight();
				}
			};

			size.height -= hh;


			item.setSize(size);
		}
	},


	setActiveItem : function(item){
		this.setActive(item, true);
	},


	setActive : function(item, expand){
		var ai = this.activeItem;
		item = this.container.getComponent(item);
		if(ai != item){
			if(item.rendered && item.collapsed && expand){
				item.expand();
			}else{
				if(ai){
					ai.fireEvent('deactivate', ai);
				}
				this.activeItem = item;
				item.fireEvent('activate', item);
			}
		}
	}
});
Ext.Container.LAYOUTS.accordion = Ext.layout.AccordionLayout;


Ext.layout.Accordion = Ext.layout.AccordionLayout;
Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, {



	monitorResize:false,

	type: 'table',

	targetCls: 'x-table-layout-ct',


	tableAttrs:null,


	setContainer : function(ct){
		Ext.layout.TableLayout.superclass.setContainer.call(this, ct);

		this.currentRow = 0;
		this.currentColumn = 0;
		this.cells = [];
	},


	onLayout : function(ct, target){
		var cs = ct.items.items, len = cs.length, c, i;

		if(!this.table){
			target.addClass('x-table-layout-ct');

			this.table = target.createChild(
				Ext.apply({
					tag:'table',
					cls:'x-table-layout',
					cellspacing: 0,
					cn: {
						tag: 'tbody'
					}
				}, this.tableAttrs), null, true);
	}
	this.renderAll(ct, target);
},


getRow : function(index){
	var row = this.table.tBodies[0].childNodes[index];
	if(!row){
		row = document.createElement('tr');
		this.table.tBodies[0].appendChild(row);
	}
	return row;
},


getNextCell : function(c){
	var cell = this.getNextNonSpan(this.currentColumn, this.currentRow);
	var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1];
	for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){
		if(!this.cells[rowIndex]){
			this.cells[rowIndex] = [];
		}
		for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){
			this.cells[rowIndex][colIndex] = true;
		}
	}
	var td = document.createElement('td');
	if(c.cellId){
		td.id = c.cellId;
	}
	var cls = 'x-table-layout-cell';
	if(c.cellCls){
		cls += ' ' + c.cellCls;
	}
	td.className = cls;
	if(c.colspan){
		td.colSpan = c.colspan;
	}
	if(c.rowspan){
		td.rowSpan = c.rowspan;
	}
	this.getRow(curRow).appendChild(td);
	return td;
},


getNextNonSpan: function(colIndex, rowIndex){
	var cols = this.columns;
	while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) {
		if(cols && colIndex >= cols){
			rowIndex++;
			colIndex = 0;
		}else{
			colIndex++;
		}
	}
	return [colIndex, rowIndex];
},


renderItem : function(c, position, target){

	if(!this.table){
		this.table = target.createChild(
			Ext.apply({
				tag:'table',
				cls:'x-table-layout',
				cellspacing: 0,
				cn: {
					tag: 'tbody'
				}
			}, this.tableAttrs), null, true);
}
if(c && !c.rendered){
	c.render(this.getNextCell(c));
	this.configureItem(c);
}else if(c && !this.isValidParent(c, target)){
	var container = this.getNextCell(c);
	container.insertBefore(c.getPositionEl().dom, null);
	c.container = Ext.get(container);
	this.configureItem(c);
}
},


isValidParent : function(c, target){
	return c.getPositionEl().up('table', 5).dom.parentNode === (target.dom || target);
},

destroy: function(){
	delete this.table;
	Ext.layout.TableLayout.superclass.destroy.call(this);
}


});

Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;
Ext.layout.AbsoluteLayout = Ext.extend(Ext.layout.AnchorLayout, {

	extraCls: 'x-abs-layout-item',

	type: 'absolute',

	onLayout : function(ct, target){
		target.position();
		this.paddingLeft = target.getPadding('l');
		this.paddingTop = target.getPadding('t');
		Ext.layout.AbsoluteLayout.superclass.onLayout.call(this, ct, target);
	},


	adjustWidthAnchor : function(value, comp){
		return value ? value - comp.getPosition(true)[0] + this.paddingLeft : value;
	},


	adjustHeightAnchor : function(value, comp){
		return  value ? value - comp.getPosition(true)[1] + this.paddingTop : value;
	}

});
Ext.Container.LAYOUTS['absolute'] = Ext.layout.AbsoluteLayout;

Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, {

	defaultMargins : {
		left:0,
		top:0,
		right:0,
		bottom:0
	},

	padding : '0',

	pack : 'start',


	monitorResize : true,
	type: 'box',
	scrollOffset : 0,
	extraCls : 'x-box-item',
	targetCls : 'x-box-layout-ct',
	innerCls : 'x-box-inner',

	constructor : function(config){
		Ext.layout.BoxLayout.superclass.constructor.call(this, config);

		if (Ext.isString(this.defaultMargins)) {
			this.defaultMargins = this.parseMargins(this.defaultMargins);
		}

		var handler = this.overflowHandler;

		if (typeof handler == 'string') {
			handler = {
				type: handler
			};
		}

		var handlerType = 'none';
		if (handler && handler.type != undefined) {
			handlerType = handler.type;
		}

		var constructor = Ext.layout.boxOverflow[handlerType];
		if (constructor[this.type]) {
			constructor = constructor[this.type];
		}

		this.overflowHandler = new constructor(this, handler);
	},


	onLayout: function(container, target) {
		Ext.layout.BoxLayout.superclass.onLayout.call(this, container, target);

		var tSize = this.getLayoutTargetSize(),
		items = this.getVisibleItems(container),
		calcs = this.calculateChildBoxes(items, tSize),
		boxes = calcs.boxes,
		meta  = calcs.meta;


		if (tSize.width > 0) {
			var handler = this.overflowHandler,
			method  = meta.tooNarrow ? 'handleOverflow' : 'clearOverflow';

			var results = handler[method](calcs, tSize);

			if (results) {
				if (results.targetSize) {
					tSize = results.targetSize;
				}

				if (results.recalculate) {
					items = this.getVisibleItems(container);
					calcs = this.calculateChildBoxes(items, tSize);
					boxes = calcs.boxes;
				}
			}
		}


		this.layoutTargetLastSize = tSize;


		this.childBoxCache = calcs;

		this.updateInnerCtSize(tSize, calcs);
		this.updateChildBoxes(boxes);


		this.handleTargetOverflow(tSize, container, target);
	},


	updateChildBoxes: function(boxes) {
		for (var i = 0, length = boxes.length; i < length; i++) {
			var box  = boxes[i],
			comp = box.component;

			if (box.dirtySize) {
				comp.setSize(box.width, box.height);
			}

			if (isNaN(box.left) || isNaN(box.top)) {
				continue;
			}

			comp.setPosition(box.left, box.top);
		}
	},


	updateInnerCtSize: function(tSize, calcs) {
		var align   = this.align,
		padding = this.padding,
		width   = tSize.width,
		height  = tSize.height;

		if (this.type == 'hbox') {
			var innerCtWidth  = width,
			innerCtHeight = calcs.meta.maxHeight + padding.top + padding.bottom;

			if (align == 'stretch') {
				innerCtHeight = height;
			} else if (align == 'middle') {
				innerCtHeight = Math.max(height, innerCtHeight);
			}
		} else {
			var innerCtHeight = height,
			innerCtWidth  = calcs.meta.maxWidth + padding.left + padding.right;

			if (align == 'stretch') {
				innerCtWidth = width;
			} else if (align == 'center') {
				innerCtWidth = Math.max(width, innerCtWidth);
			}
		}

		this.innerCt.setSize(innerCtWidth || undefined, innerCtHeight || undefined);
	},


	handleTargetOverflow: function(previousTargetSize, container, target) {
		var overflow = target.getStyle('overflow');

		if (overflow && overflow != 'hidden' &&!this.adjustmentPass) {
			var newTargetSize = this.getLayoutTargetSize();
			if (newTargetSize.width != previousTargetSize.width || newTargetSize.height != previousTargetSize.height){
				this.adjustmentPass = true;
				this.onLayout(container, target);
			}
		}

		delete this.adjustmentPass;
	},


	isValidParent : function(c, target) {
		return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom;
	},


	getVisibleItems: function(ct) {
		var ct  = ct || this.container,
		t   = ct.getLayoutTarget(),
		cti = ct.items.items,
		len = cti.length,

		i, c, items = [];

		for (i = 0; i < len; i++) {
			if((c = cti[i]).rendered && this.isValidParent(c, t) && c.hidden !== true  && c.collapsed !== true && c.shouldLayout !== false){
				items.push(c);
			}
		}

		return items;
	},


	renderAll : function(ct, target) {
		if (!this.innerCt) {

			this.innerCt = target.createChild({
				cls:this.innerCls
				});
			this.padding = this.parseMargins(this.padding);
		}
		Ext.layout.BoxLayout.superclass.renderAll.call(this, ct, this.innerCt);
	},

	getLayoutTargetSize : function() {
		var target = this.container.getLayoutTarget(), ret;

		if (target) {
			ret = target.getViewSize();




			if (Ext.isIE && Ext.isStrict && ret.width == 0){
				ret =  target.getStyleSize();
			}

			ret.width  -= target.getPadding('lr');
			ret.height -= target.getPadding('tb');
		}

		return ret;
	},


	renderItem : function(c) {
		if(Ext.isString(c.margins)){
			c.margins = this.parseMargins(c.margins);
		}else if(!c.margins){
			c.margins = this.defaultMargins;
		}
		Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments);
	},


	destroy: function() {
		Ext.destroy(this.overflowHandler);

		Ext.layout.BoxLayout.superclass.destroy.apply(this, arguments);
	}
});



Ext.ns('Ext.layout.boxOverflow');



Ext.layout.boxOverflow.None = Ext.extend(Object, {
	constructor: function(layout, config) {
		this.layout = layout;

		Ext.apply(this, config || {});
	},

	handleOverflow: Ext.emptyFn,

	clearOverflow: Ext.emptyFn
});


Ext.layout.boxOverflow.none = Ext.layout.boxOverflow.None;

Ext.layout.boxOverflow.Menu = Ext.extend(Ext.layout.boxOverflow.None, {

	afterCls: 'x-strip-right',


	noItemsMenuText : '<div class="x-toolbar-no-items">(None)</div>',

	constructor: function(layout) {
		Ext.layout.boxOverflow.Menu.superclass.constructor.apply(this, arguments);


		this.menuItems = [];
	},


	createInnerElements: function() {
		if (!this.afterCt) {
			this.afterCt  = this.layout.innerCt.insertSibling({
				cls: this.afterCls
				},  'before');
		}
	},


	clearOverflow: function(calculations, targetSize) {
		var newWidth = targetSize.width + (this.afterCt ? this.afterCt.getWidth() : 0),
		items    = this.menuItems;

		this.hideTrigger();

		for (var index = 0, length = items.length; index < length; index++) {
			items.pop().component.show();
		}

		return {
			targetSize: {
				height: targetSize.height,
				width : newWidth
			}
		};
	},


	showTrigger: function() {
		this.createMenu();
		this.menuTrigger.show();
	},


	hideTrigger: function() {
		if (this.menuTrigger != undefined) {
			this.menuTrigger.hide();
		}
	},


	beforeMenuShow: function(menu) {
		var items = this.menuItems,
		len   = items.length,
		item,
		prev;

		var needsSep = function(group, item){
			return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator);
		};

		this.clearMenu();
		menu.removeAll();

		for (var i = 0; i < len; i++) {
			item = items[i].component;

			if (prev && (needsSep(item, prev) || needsSep(prev, item))) {
				menu.add('-');
			}

			this.addComponentToMenu(menu, item);
			prev = item;
		}


		if (menu.items.length < 1) {
			menu.add(this.noItemsMenuText);
		}
	},


	createMenuConfig : function(component, hideOnClick){
		var config = Ext.apply({}, component.initialConfig),
		group  = component.toggleGroup;

		Ext.copyTo(config, component, [
			'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu'
			]);

		Ext.apply(config, {
			text       : component.overflowText || component.text,
			hideOnClick: hideOnClick
		});

		if (group || component.enableToggle) {
			Ext.apply(config, {
				group  : group,
				checked: component.pressed,
				listeners: {
					checkchange: function(item, checked){
						component.toggle(checked);
					}
				}
			});
		}

		delete config.ownerCt;
		delete config.xtype;
		delete config.id;

		return config;
	},


	addComponentToMenu : function(menu, component) {
		if (component instanceof Ext.Toolbar.Separator) {
			menu.add('-');

		} else if (Ext.isFunction(component.isXType)) {
			if (component.isXType('splitbutton')) {
				menu.add(this.createMenuConfig(component, true));

			} else if (component.isXType('button')) {
				menu.add(this.createMenuConfig(component, !component.menu));

			} else if (component.isXType('buttongroup')) {
				component.items.each(function(item){
					this.addComponentToMenu(menu, item);
				}, this);
			}
		}
	},


	clearMenu : function(){
		var menu = this.moreMenu;
		if (menu && menu.items) {
			menu.items.each(function(item){
				delete item.menu;
			});
		}
	},


	createMenu: function() {
		if (!this.menuTrigger) {
			this.createInnerElements();


			this.menu = new Ext.menu.Menu({
				ownerCt : this.layout.container,
				listeners: {
					scope: this,
					beforeshow: this.beforeMenuShow
				}
			});


			this.menuTrigger = new Ext.Button({
				iconCls : 'x-toolbar-more-icon',
				cls     : 'x-toolbar-more',
				menu    : this.menu,
				renderTo: this.afterCt
			});
		}
	},


	destroy: function() {
		Ext.destroy(this.menu, this.menuTrigger);
	}
});

Ext.layout.boxOverflow.menu = Ext.layout.boxOverflow.Menu;



Ext.layout.boxOverflow.HorizontalMenu = Ext.extend(Ext.layout.boxOverflow.Menu, {

	constructor: function() {
		Ext.layout.boxOverflow.HorizontalMenu.superclass.constructor.apply(this, arguments);

		var me = this,
		layout = me.layout,
		origFunction = layout.calculateChildBoxes;

		layout.calculateChildBoxes = function(visibleItems, targetSize) {
			var calcs = origFunction.apply(layout, arguments),
			meta  = calcs.meta,
			items = me.menuItems;



			var hiddenWidth = 0;
			for (var index = 0, length = items.length; index < length; index++) {
				hiddenWidth += items[index].width;
			}

			meta.minimumWidth += hiddenWidth;
			meta.tooNarrow = meta.minimumWidth > targetSize.width;

			return calcs;
		};
	},

	handleOverflow: function(calculations, targetSize) {
		this.showTrigger();

		var newWidth    = targetSize.width - this.afterCt.getWidth(),
		boxes       = calculations.boxes,
		usedWidth   = 0,
		recalculate = false;


		for (var index = 0, length = boxes.length; index < length; index++) {
			usedWidth += boxes[index].width;
		}

		var spareWidth = newWidth - usedWidth,
		showCount  = 0;


		for (var index = 0, length = this.menuItems.length; index < length; index++) {
			var hidden = this.menuItems[index],
			comp   = hidden.component,
			width  = hidden.width;

			if (width < spareWidth) {
				comp.show();

				spareWidth -= width;
				showCount ++;
				recalculate = true;
			} else {
				break;
			}
		}

		if (recalculate) {
			this.menuItems = this.menuItems.slice(showCount);
		} else {
			for (var i = boxes.length - 1; i >= 0; i--) {
				var item  = boxes[i].component,
				right = boxes[i].left + boxes[i].width;

				if (right >= newWidth) {
					this.menuItems.unshift({
						component: item,
						width    : boxes[i].width
					});

					item.hide();
				} else {
					break;
				}
			}
		}

		if (this.menuItems.length == 0) {
			this.hideTrigger();
		}

		return {
			targetSize: {
				height: targetSize.height,
				width : newWidth
			},
			recalculate: recalculate
		};
	}
});

Ext.layout.boxOverflow.menu.hbox = Ext.layout.boxOverflow.HorizontalMenu;
Ext.layout.boxOverflow.Scroller = Ext.extend(Ext.layout.boxOverflow.None, {

	animateScroll: true,


	scrollIncrement: 100,


	wheelIncrement: 3,


	scrollRepeatInterval: 400,


	scrollDuration: 0.4,


	beforeCls: 'x-strip-left',


	afterCls: 'x-strip-right',


	scrollerCls: 'x-strip-scroller',


	beforeScrollerCls: 'x-strip-scroller-left',


	afterScrollerCls: 'x-strip-scroller-right',


	createWheelListener: function() {
		this.layout.innerCt.on({
			scope     : this,
			mousewheel: function(e) {
				e.stopEvent();

				this.scrollBy(e.getWheelDelta() * this.wheelIncrement * -1, false);
			}
		});
	},


	handleOverflow: function(calculations, targetSize) {
		this.createInnerElements();
		this.showScrollers();
	},


	clearOverflow: function() {
		this.hideScrollers();
	},


	showScrollers: function() {
		this.createScrollers();

		this.beforeScroller.show();
		this.afterScroller.show();

		this.updateScrollButtons();
	},


	hideScrollers: function() {
		if (this.beforeScroller != undefined) {
			this.beforeScroller.hide();
			this.afterScroller.hide();
		}
	},


	createScrollers: function() {
		if (!this.beforeScroller && !this.afterScroller) {
			var before = this.beforeCt.createChild({
				cls: String.format("{0} {1} ", this.scrollerCls, this.beforeScrollerCls)
			});

			var after = this.afterCt.createChild({
				cls: String.format("{0} {1}", this.scrollerCls, this.afterScrollerCls)
			});

			before.addClassOnOver(this.beforeScrollerCls + '-hover');
			after.addClassOnOver(this.afterScrollerCls + '-hover');

			before.setVisibilityMode(Ext.Element.DISPLAY);
			after.setVisibilityMode(Ext.Element.DISPLAY);

			this.beforeRepeater = new Ext.util.ClickRepeater(before, {
				interval: this.scrollRepeatInterval,
				handler : this.scrollLeft,
				scope   : this
			});

			this.afterRepeater = new Ext.util.ClickRepeater(after, {
				interval: this.scrollRepeatInterval,
				handler : this.scrollRight,
				scope   : this
			});


			this.beforeScroller = before;


			this.afterScroller = after;
		}
	},


	destroy: function() {
		Ext.destroy(this.beforeScroller, this.afterScroller, this.beforeRepeater, this.afterRepeater, this.beforeCt, this.afterCt);
	},


	scrollBy: function(delta, animate) {
		this.scrollTo(this.getScrollPosition() + delta, animate);
	},


	getItem: function(item) {
		if (Ext.isString(item)) {
			item = Ext.getCmp(item);
		} else if (Ext.isNumber(item)) {
			item = this.items[item];
		}

		return item;
	},


	getScrollAnim: function() {
		return {
			duration: this.scrollDuration,
			callback: this.updateScrollButtons,
			scope   : this
		};
	},


	updateScrollButtons: function() {
		if (this.beforeScroller == undefined || this.afterScroller == undefined) {
			return;
		}

		var beforeMeth = this.atExtremeBefore()  ? 'addClass' : 'removeClass',
		afterMeth  = this.atExtremeAfter() ? 'addClass' : 'removeClass',
		beforeCls  = this.beforeScrollerCls + '-disabled',
		afterCls   = this.afterScrollerCls  + '-disabled';

		this.beforeScroller[beforeMeth](beforeCls);
		this.afterScroller[afterMeth](afterCls);
		this.scrolling = false;
	},


	atExtremeBefore: function() {
		return this.getScrollPosition() === 0;
	},


	scrollLeft: function(animate) {
		this.scrollBy(-this.scrollIncrement, animate);
	},


	scrollRight: function(animate) {
		this.scrollBy(this.scrollIncrement, animate);
	},


	scrollToItem: function(item, animate) {
		item = this.getItem(item);

		if (item != undefined) {
			var visibility = this.getItemVisibility(item);

			if (!visibility.fullyVisible) {
				var box  = item.getBox(true, true),
				newX = box.x;

				if (visibility.hiddenRight) {
					newX -= (this.layout.innerCt.getWidth() - box.width);
				}

				this.scrollTo(newX, animate);
			}
		}
	},


	getItemVisibility: function(item) {
		var box         = this.getItem(item).getBox(true, true),
		itemLeft    = box.x,
		itemRight   = box.x + box.width,
		scrollLeft  = this.getScrollPosition(),
		scrollRight = this.layout.innerCt.getWidth() + scrollLeft;

		return {
			hiddenLeft  : itemLeft < scrollLeft,
			hiddenRight : itemRight > scrollRight,
			fullyVisible: itemLeft > scrollLeft && itemRight < scrollRight
		};
	}
});

Ext.layout.boxOverflow.scroller = Ext.layout.boxOverflow.Scroller;



Ext.layout.boxOverflow.VerticalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, {
	scrollIncrement: 75,
	wheelIncrement : 2,

	handleOverflow: function(calculations, targetSize) {
		Ext.layout.boxOverflow.VerticalScroller.superclass.handleOverflow.apply(this, arguments);

		return {
			targetSize: {
				height: targetSize.height - (this.beforeCt.getHeight() + this.afterCt.getHeight()),
				width : targetSize.width
			}
		};
	},


	createInnerElements: function() {
		var target = this.layout.innerCt;



		if (!this.beforeCt) {
			this.beforeCt = target.insertSibling({
				cls: this.beforeCls
				}, 'before');
			this.afterCt  = target.insertSibling({
				cls: this.afterCls
				},  'after');

			this.createWheelListener();
		}
	},


	scrollTo: function(position, animate) {
		var oldPosition = this.getScrollPosition(),
		newPosition = position.constrain(0, this.getMaxScrollBottom());

		if (newPosition != oldPosition && !this.scrolling) {
			if (animate == undefined) {
				animate = this.animateScroll;
			}

			this.layout.innerCt.scrollTo('top', newPosition, animate ? this.getScrollAnim() : false);

			if (animate) {
				this.scrolling = true;
			} else {
				this.scrolling = false;
				this.updateScrollButtons();
			}
		}
	},


	getScrollPosition: function(){
		return parseInt(this.layout.innerCt.dom.scrollTop, 10) || 0;
	},


	getMaxScrollBottom: function() {
		return this.layout.innerCt.dom.scrollHeight - this.layout.innerCt.getHeight();
	},


	atExtremeAfter: function() {
		return this.getScrollPosition() >= this.getMaxScrollBottom();
	}
});

Ext.layout.boxOverflow.scroller.vbox = Ext.layout.boxOverflow.VerticalScroller;



Ext.layout.boxOverflow.HorizontalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, {
	handleOverflow: function(calculations, targetSize) {
		Ext.layout.boxOverflow.HorizontalScroller.superclass.handleOverflow.apply(this, arguments);

		return {
			targetSize: {
				height: targetSize.height,
				width : targetSize.width - (this.beforeCt.getWidth() + this.afterCt.getWidth())
			}
		};
	},


	createInnerElements: function() {
		var target = this.layout.innerCt;



		if (!this.beforeCt) {
			this.afterCt  = target.insertSibling({
				cls: this.afterCls
				},  'before');
			this.beforeCt = target.insertSibling({
				cls: this.beforeCls
				}, 'before');

			this.createWheelListener();
		}
	},


	scrollTo: function(position, animate) {
		var oldPosition = this.getScrollPosition(),
		newPosition = position.constrain(0, this.getMaxScrollRight());

		if (newPosition != oldPosition && !this.scrolling) {
			if (animate == undefined) {
				animate = this.animateScroll;
			}

			this.layout.innerCt.scrollTo('left', newPosition, animate ? this.getScrollAnim() : false);

			if (animate) {
				this.scrolling = true;
			} else {
				this.scrolling = false;
				this.updateScrollButtons();
			}
		}
	},


	getScrollPosition: function(){
		return parseInt(this.layout.innerCt.dom.scrollLeft, 10) || 0;
	},


	getMaxScrollRight: function() {
		return this.layout.innerCt.dom.scrollWidth - this.layout.innerCt.getWidth();
	},


	atExtremeAfter: function() {
		return this.getScrollPosition() >= this.getMaxScrollRight();
	}
});

Ext.layout.boxOverflow.scroller.hbox = Ext.layout.boxOverflow.HorizontalScroller;
Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, {

	align: 'top',

	type : 'hbox',





	calculateChildBoxes: function(visibleItems, targetSize) {
		var visibleCount = visibleItems.length,

		padding      = this.padding,
		topOffset    = padding.top,
		leftOffset   = padding.left,
		paddingVert  = topOffset  + padding.bottom,
		paddingHoriz = leftOffset + padding.right,

		width        = targetSize.width - this.scrollOffset,
		height       = targetSize.height,
		availHeight  = Math.max(0, height - paddingVert),

		isStart      = this.pack == 'start',
		isCenter     = this.pack == 'center',
		isEnd        = this.pack == 'end',

		nonFlexWidth = 0,
		maxHeight    = 0,
		totalFlex    = 0,
		desiredWidth = 0,
		minimumWidth = 0,


		boxes        = [],


		child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedWidth,
		horizMargins, vertMargins, stretchHeight;


		for (i = 0; i < visibleCount; i++) {
			child       = visibleItems[i];
			childHeight = child.height;
			childWidth  = child.width;
			canLayout   = !child.hasLayout && typeof child.doLayout == 'function';


			if (typeof childWidth != 'number') {


				if (child.flex && !childWidth) {
					totalFlex += child.flex;


				} else {


					if (!childWidth && canLayout) {
						child.doLayout();
					}

					childSize   = child.getSize();
					childWidth  = childSize.width;
					childHeight = childSize.height;
				}
			}

			childMargins = child.margins;
			horizMargins = childMargins.left + childMargins.right;

			nonFlexWidth += horizMargins + (childWidth || 0);
			desiredWidth += horizMargins + (child.flex ? child.minWidth || 0 : childWidth);
			minimumWidth += horizMargins + (child.minWidth || childWidth || 0);


			if (typeof childHeight != 'number') {
				if (canLayout) {
					child.doLayout();
				}
				childHeight = child.getHeight();
			}

			maxHeight = Math.max(maxHeight, childHeight + childMargins.top + childMargins.bottom);


			boxes.push({
				component: child,
				height   : childHeight || undefined,
				width    : childWidth  || undefined
			});
		}

		var shortfall = desiredWidth - width,
		tooNarrow = minimumWidth > width;


		var availableWidth = Math.max(0, width - nonFlexWidth - paddingHoriz);

		if (tooNarrow) {
			for (i = 0; i < visibleCount; i++) {
				boxes[i].width = visibleItems[i].minWidth || visibleItems[i].width || boxes[i].width;
			}
		} else {


			if (shortfall > 0) {
				var minWidths = [];


				for (var index = 0, length = visibleCount; index < length; index++) {
					var item     = visibleItems[index],
					minWidth = item.minWidth || 0;



					if (item.flex) {
						boxes[index].width = minWidth;
					} else {
						minWidths.push({
							minWidth : minWidth,
							available: boxes[index].width - minWidth,
							index    : index
						});
					}
				}


				minWidths.sort(function(a, b) {
					return a.available > b.available ? 1 : -1;
				});


				for (var i = 0, length = minWidths.length; i < length; i++) {
					var itemIndex = minWidths[i].index;

					if (itemIndex == undefined) {
						continue;
					}

					var item      = visibleItems[itemIndex],
					box       = boxes[itemIndex],
					oldWidth  = box.width,
					minWidth  = item.minWidth,
					newWidth  = Math.max(minWidth, oldWidth - Math.ceil(shortfall / (length - i))),
					reduction = oldWidth - newWidth;

					boxes[itemIndex].width = newWidth;
					shortfall -= reduction;
				}
			} else {

				var remainingWidth = availableWidth,
				remainingFlex  = totalFlex;


				for (i = 0; i < visibleCount; i++) {
					child = visibleItems[i];
					calcs = boxes[i];

					childMargins = child.margins;
					vertMargins  = childMargins.top + childMargins.bottom;

					if (isStart && child.flex && !child.width) {
						flexedWidth     = Math.ceil((child.flex / remainingFlex) * remainingWidth);
						remainingWidth -= flexedWidth;
						remainingFlex  -= child.flex;

						calcs.width = flexedWidth;
						calcs.dirtySize = true;
					}
				}
			}
		}

		if (isCenter) {
			leftOffset += availableWidth / 2;
		} else if (isEnd) {
			leftOffset += availableWidth;
		}


		for (i = 0; i < visibleCount; i++) {
			child = visibleItems[i];
			calcs = boxes[i];

			childMargins = child.margins;
			leftOffset  += childMargins.left;
			vertMargins  = childMargins.top + childMargins.bottom;

			calcs.left = leftOffset;
			calcs.top  = topOffset + childMargins.top;

			switch (this.align) {
				case 'stretch':
					stretchHeight = availHeight - vertMargins;
					calcs.height  = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
					calcs.dirtySize = true;
					break;
				case 'stretchmax':
					stretchHeight = maxHeight - vertMargins;
					calcs.height  = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
					calcs.dirtySize = true;
					break;
				case 'middle':
					var diff = availHeight - calcs.height - vertMargins;
					if (diff > 0) {
						calcs.top = topOffset + vertMargins + (diff / 2);
					}
			}

			leftOffset += calcs.width + childMargins.right;
		}

		return {
			boxes: boxes,
			meta : {
				maxHeight   : maxHeight,
				nonFlexWidth: nonFlexWidth,
				desiredWidth: desiredWidth,
				minimumWidth: minimumWidth,
				shortfall   : desiredWidth - width,
				tooNarrow   : tooNarrow
			}
		};
	}
});

Ext.Container.LAYOUTS.hbox = Ext.layout.HBoxLayout;
Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, {

	align : 'left',
	type: 'vbox',






	calculateChildBoxes: function(visibleItems, targetSize) {
		var visibleCount = visibleItems.length,

		padding      = this.padding,
		topOffset    = padding.top,
		leftOffset   = padding.left,
		paddingVert  = topOffset  + padding.bottom,
		paddingHoriz = leftOffset + padding.right,

		width        = targetSize.width - this.scrollOffset,
		height       = targetSize.height,
		availWidth   = Math.max(0, width - paddingHoriz),

		isStart      = this.pack == 'start',
		isCenter     = this.pack == 'center',
		isEnd        = this.pack == 'end',

		nonFlexHeight= 0,
		maxWidth     = 0,
		totalFlex    = 0,
		desiredHeight= 0,
		minimumHeight= 0,


		boxes        = [],


		child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedWidth,
		horizMargins, vertMargins, stretchWidth;


		for (i = 0; i < visibleCount; i++) {
			child = visibleItems[i];
			childHeight = child.height;
			childWidth  = child.width;
			canLayout   = !child.hasLayout && typeof child.doLayout == 'function';


			if (typeof childHeight != 'number') {


				if (child.flex && !childHeight) {
					totalFlex += child.flex;


				} else {


					if (!childHeight && canLayout) {
						child.doLayout();
					}

					childSize = child.getSize();
					childWidth = childSize.width;
					childHeight = childSize.height;
				}
			}

			childMargins = child.margins;
			vertMargins  = childMargins.top + childMargins.bottom;

			nonFlexHeight += vertMargins + (childHeight || 0);
			desiredHeight += vertMargins + (child.flex ? child.minHeight || 0 : childHeight);
			minimumHeight += vertMargins + (child.minHeight || childHeight || 0);


			if (typeof childWidth != 'number') {
				if (canLayout) {
					child.doLayout();
				}
				childWidth = child.getWidth();
			}

			maxWidth = Math.max(maxWidth, childWidth + childMargins.left + childMargins.right);


			boxes.push({
				component: child,
				height   : childHeight || undefined,
				width    : childWidth || undefined
			});
		}

		var shortfall = desiredHeight - height,
		tooNarrow = minimumHeight > height;


		var availableHeight = Math.max(0, (height - nonFlexHeight - paddingVert));

		if (tooNarrow) {
			for (i = 0, length = visibleCount; i < length; i++) {
				boxes[i].height = visibleItems[i].minHeight || visibleItems[i].height || boxes[i].height;
			}
		} else {


			if (shortfall > 0) {
				var minHeights = [];


				for (var index = 0, length = visibleCount; index < length; index++) {
					var item      = visibleItems[index],
					minHeight = item.minHeight || 0;



					if (item.flex) {
						boxes[index].height = minHeight;
					} else {
						minHeights.push({
							minHeight: minHeight,
							available: boxes[index].height - minHeight,
							index    : index
						});
					}
				}


				minHeights.sort(function(a, b) {
					return a.available > b.available ? 1 : -1;
				});


				for (var i = 0, length = minHeights.length; i < length; i++) {
					var itemIndex = minHeights[i].index;

					if (itemIndex == undefined) {
						continue;
					}

					var item      = visibleItems[itemIndex],
					box       = boxes[itemIndex],
					oldHeight  = box.height,
					minHeight  = item.minHeight,
					newHeight  = Math.max(minHeight, oldHeight - Math.ceil(shortfall / (length - i))),
					reduction = oldHeight - newHeight;

					boxes[itemIndex].height = newHeight;
					shortfall -= reduction;
				}
			} else {

				var remainingHeight = availableHeight,
				remainingFlex   = totalFlex;


				for (i = 0; i < visibleCount; i++) {
					child = visibleItems[i];
					calcs = boxes[i];

					childMargins = child.margins;
					horizMargins = childMargins.left + childMargins.right;

					if (isStart && child.flex && !child.height) {
						flexedHeight     = Math.ceil((child.flex / remainingFlex) * remainingHeight);
						remainingHeight -= flexedHeight;
						remainingFlex   -= child.flex;

						calcs.height = flexedHeight;
						calcs.dirtySize = true;
					}
				}
			}
		}

		if (isCenter) {
			topOffset += availableHeight / 2;
		} else if (isEnd) {
			topOffset += availableHeight;
		}


		for (i = 0; i < visibleCount; i++) {
			child = visibleItems[i];
			calcs = boxes[i];

			childMargins = child.margins;
			topOffset   += childMargins.top;
			horizMargins = childMargins.left + childMargins.right;


			calcs.left = leftOffset + childMargins.left;
			calcs.top  = topOffset;

			switch (this.align) {
				case 'stretch':
					stretchWidth = availWidth - horizMargins;
					calcs.width  = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
					calcs.dirtySize = true;
					break;
				case 'stretchmax':
					stretchWidth = maxWidth - horizMargins;
					calcs.width  = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
					calcs.dirtySize = true;
					break;
				case 'center':
					var diff = availWidth - calcs.width - horizMargins;
					if (diff > 0) {
						calcs.left = leftOffset + horizMargins + (diff / 2);
					}
			}

			topOffset += calcs.height + childMargins.bottom;
		}

		return {
			boxes: boxes,
			meta : {
				maxWidth     : maxWidth,
				nonFlexHeight: nonFlexHeight,
				desiredHeight: desiredHeight,
				minimumHeight: minimumHeight,
				shortfall    : desiredHeight - height,
				tooNarrow    : tooNarrow
			}
		};
	}
});

Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout;

Ext.layout.ToolbarLayout = Ext.extend(Ext.layout.ContainerLayout, {
	monitorResize : true,

	type: 'toolbar',


	triggerWidth: 18,


	noItemsMenuText : '<div class="x-toolbar-no-items">(None)</div>',


	lastOverflow: false,


	tableHTML: [
	'<table cellspacing="0" class="x-toolbar-ct">',
	'<tbody>',
	'<tr>',
	'<td class="x-toolbar-left" align="{0}">',
	'<table cellspacing="0">',
	'<tbody>',
	'<tr class="x-toolbar-left-row"></tr>',
	'</tbody>',
	'</table>',
	'</td>',
	'<td class="x-toolbar-right" align="right">',
	'<table cellspacing="0" class="x-toolbar-right-ct">',
	'<tbody>',
	'<tr>',
	'<td>',
	'<table cellspacing="0">',
	'<tbody>',
	'<tr class="x-toolbar-right-row"></tr>',
	'</tbody>',
	'</table>',
	'</td>',
	'<td>',
	'<table cellspacing="0">',
	'<tbody>',
	'<tr class="x-toolbar-extras-row"></tr>',
	'</tbody>',
	'</table>',
	'</td>',
	'</tr>',
	'</tbody>',
	'</table>',
	'</td>',
	'</tr>',
	'</tbody>',
	'</table>'
	].join(""),


	onLayout : function(ct, target) {

		if (!this.leftTr) {
			var align = ct.buttonAlign == 'center' ? 'center' : 'left';

			target.addClass('x-toolbar-layout-ct');
			target.insertHtml('beforeEnd', String.format(this.tableHTML, align));

			this.leftTr   = target.child('tr.x-toolbar-left-row', true);
			this.rightTr  = target.child('tr.x-toolbar-right-row', true);
			this.extrasTr = target.child('tr.x-toolbar-extras-row', true);

			if (this.hiddenItem == undefined) {

				this.hiddenItems = [];
			}
		}

		var side     = ct.buttonAlign == 'right' ? this.rightTr : this.leftTr,
		items    = ct.items.items,
		position = 0;


		for (var i = 0, len = items.length, c; i < len; i++, position++) {
			c = items[i];

			if (c.isFill) {
				side   = this.rightTr;
				position = -1;
			} else if (!c.rendered) {
				c.render(this.insertCell(c, side, position));
				this.configureItem(c);
			} else {
				if (!c.xtbHidden && !this.isValidParent(c, side.childNodes[position])) {
					var td = this.insertCell(c, side, position);
					td.appendChild(c.getPositionEl().dom);
					c.container = Ext.get(td);
				}
			}
		}


		this.cleanup(this.leftTr);
		this.cleanup(this.rightTr);
		this.cleanup(this.extrasTr);
		this.fitToSize(target);
	},


	cleanup : function(el) {
		var cn = el.childNodes, i, c;

		for (i = cn.length-1; i >= 0 && (c = cn[i]); i--) {
			if (!c.firstChild) {
				el.removeChild(c);
			}
		}
	},


	insertCell : function(c, target, position) {
		var td = document.createElement('td');
		td.className = 'x-toolbar-cell';

		target.insertBefore(td, target.childNodes[position] || null);

		return td;
	},


	hideItem : function(item) {
		this.hiddenItems.push(item);

		item.xtbHidden = true;
		item.xtbWidth = item.getPositionEl().dom.parentNode.offsetWidth;
		item.hide();
	},


	unhideItem : function(item) {
		item.show();
		item.xtbHidden = false;
		this.hiddenItems.remove(item);
	},


	getItemWidth : function(c) {
		return c.hidden ? (c.xtbWidth || 0) : c.getPositionEl().dom.parentNode.offsetWidth;
	},


	fitToSize : function(target) {
		if (this.container.enableOverflow === false) {
			return;
		}

		var width       = target.dom.clientWidth,
		tableWidth  = target.dom.firstChild.offsetWidth,
		clipWidth   = width - this.triggerWidth,
		lastWidth   = this.lastWidth || 0,

		hiddenItems = this.hiddenItems,
		hasHiddens  = hiddenItems.length != 0,
		isLarger    = width >= lastWidth;

		this.lastWidth  = width;

		if (tableWidth > width || (hasHiddens && isLarger)) {
			var items     = this.container.items.items,
			len       = items.length,
			loopWidth = 0,
			item;

			for (var i = 0; i < len; i++) {
				item = items[i];

				if (!item.isFill) {
					loopWidth += this.getItemWidth(item);
					if (loopWidth > clipWidth) {
						if (!(item.hidden || item.xtbHidden)) {
							this.hideItem(item);
						}
					} else if (item.xtbHidden) {
						this.unhideItem(item);
					}
				}
			}
		}


		hasHiddens = hiddenItems.length != 0;

		if (hasHiddens) {
			this.initMore();

			if (!this.lastOverflow) {
				this.container.fireEvent('overflowchange', this.container, true);
				this.lastOverflow = true;
			}
		} else if (this.more) {
			this.clearMenu();
			this.more.destroy();
			delete this.more;

			if (this.lastOverflow) {
				this.container.fireEvent('overflowchange', this.container, false);
				this.lastOverflow = false;
			}
		}
	},


	createMenuConfig : function(component, hideOnClick){
		var config = Ext.apply({}, component.initialConfig),
		group  = component.toggleGroup;

		Ext.copyTo(config, component, [
			'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu'
			]);

		Ext.apply(config, {
			text       : component.overflowText || component.text,
			hideOnClick: hideOnClick
		});

		if (group || component.enableToggle) {
			Ext.apply(config, {
				group  : group,
				checked: component.pressed,
				listeners: {
					checkchange: function(item, checked){
						component.toggle(checked);
					}
				}
			});
		}

		delete config.ownerCt;
		delete config.xtype;
		delete config.id;

		return config;
	},


	addComponentToMenu : function(menu, component) {
		if (component instanceof Ext.Toolbar.Separator) {
			menu.add('-');

		} else if (Ext.isFunction(component.isXType)) {
			if (component.isXType('splitbutton')) {
				menu.add(this.createMenuConfig(component, true));

			} else if (component.isXType('button')) {
				menu.add(this.createMenuConfig(component, !component.menu));

			} else if (component.isXType('buttongroup')) {
				component.items.each(function(item){
					this.addComponentToMenu(menu, item);
				}, this);
			}
		}
	},


	clearMenu : function(){
		var menu = this.moreMenu;
		if (menu && menu.items) {
			menu.items.each(function(item){
				delete item.menu;
			});
		}
	},


	beforeMoreShow : function(menu) {
		var items = this.container.items.items,
		len   = items.length,
		item,
		prev;

		var needsSep = function(group, item){
			return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator);
		};

		this.clearMenu();
		menu.removeAll();
		for (var i = 0; i < len; i++) {
			item = items[i];
			if (item.xtbHidden) {
				if (prev && (needsSep(item, prev) || needsSep(prev, item))) {
					menu.add('-');
				}
				this.addComponentToMenu(menu, item);
				prev = item;
			}
		}


		if (menu.items.length < 1) {
			menu.add(this.noItemsMenuText);
		}
	},


	initMore : function(){
		if (!this.more) {

			this.moreMenu = new Ext.menu.Menu({
				ownerCt : this.container,
				listeners: {
					beforeshow: this.beforeMoreShow,
					scope: this
				}
			});


			this.more = new Ext.Button({
				iconCls: 'x-toolbar-more-icon',
				cls    : 'x-toolbar-more',
				menu   : this.moreMenu,
				ownerCt: this.container
			});

			var td = this.insertCell(this.more, this.extrasTr, 100);
			this.more.render(td);
		}
	},

	destroy : function(){
		Ext.destroy(this.more, this.moreMenu);
		delete this.leftTr;
		delete this.rightTr;
		delete this.extrasTr;
		Ext.layout.ToolbarLayout.superclass.destroy.call(this);
	}
});

Ext.Container.LAYOUTS.toolbar = Ext.layout.ToolbarLayout;

Ext.layout.MenuLayout = Ext.extend(Ext.layout.ContainerLayout, {
	monitorResize : true,

	type: 'menu',

	setContainer : function(ct){
		this.monitorResize = !ct.floating;


		ct.on('autosize', this.doAutoSize, this);
		Ext.layout.MenuLayout.superclass.setContainer.call(this, ct);
	},

	renderItem : function(c, position, target){
		if (!this.itemTpl) {
			this.itemTpl = Ext.layout.MenuLayout.prototype.itemTpl = new Ext.XTemplate(
				'<li id="{itemId}" class="{itemCls}">',
				'<tpl if="needsIcon">',
				'<img alt="{altText}" src="{icon}" class="{iconCls}"/>',
				'</tpl>',
				'</li>'
				);
		}

		if(c && !c.rendered){
			if(Ext.isNumber(position)){
				position = target.dom.childNodes[position];
			}
			var a = this.getItemArgs(c);


			c.render(c.positionEl = position ?
				this.itemTpl.insertBefore(position, a, true) :
				this.itemTpl.append(target, a, true));


			c.positionEl.menuItemId = c.getItemId();



			if (!a.isMenuItem && a.needsIcon) {
				c.positionEl.addClass('x-menu-list-item-indent');
			}
			this.configureItem(c);
		}else if(c && !this.isValidParent(c, target)){
			if(Ext.isNumber(position)){
				position = target.dom.childNodes[position];
			}
			target.dom.insertBefore(c.getActionEl().dom, position || null);
		}
	},

	getItemArgs : function(c) {
		var isMenuItem = c instanceof Ext.menu.Item,
		canHaveIcon = !(isMenuItem || c instanceof Ext.menu.Separator);

		return {
			isMenuItem: isMenuItem,
			needsIcon: canHaveIcon && (c.icon || c.iconCls),
			icon: c.icon || Ext.BLANK_IMAGE_URL,
			iconCls: 'x-menu-item-icon ' + (c.iconCls || ''),
			itemId: 'x-menu-el-' + c.id,
			itemCls: 'x-menu-list-item ',
			altText: c.altText || ''
		};
	},


	isValidParent : function(c, target) {
		return c.el.up('li.x-menu-list-item', 5).dom.parentNode === (target.dom || target);
	},

	onLayout : function(ct, target){
		Ext.layout.MenuLayout.superclass.onLayout.call(this, ct, target);
		this.doAutoSize();
	},

	doAutoSize : function(){
		var ct = this.container, w = ct.width;
		if(ct.floating){
			if(w){
				ct.setWidth(w);
			}else if(Ext.isIE){
				ct.setWidth(Ext.isStrict && (Ext.isIE7 || Ext.isIE8) ? 'auto' : ct.minWidth);
				var el = ct.getEl(), t = el.dom.offsetWidth;
				ct.setWidth(ct.getLayoutTarget().getWidth() + el.getFrameWidth('lr'));
			}
		}
	}
});
Ext.Container.LAYOUTS['menu'] = Ext.layout.MenuLayout;

Ext.Viewport = Ext.extend(Ext.Container, {













	initComponent : function() {
		Ext.Viewport.superclass.initComponent.call(this);
		document.getElementsByTagName('html')[0].className += ' x-viewport';
		this.el = Ext.getBody();
		this.el.setHeight = Ext.emptyFn;
		this.el.setWidth = Ext.emptyFn;
		this.el.setSize = Ext.emptyFn;
		this.el.dom.scroll = 'no';
		this.allowDomMove = false;
		this.autoWidth = true;
		this.autoHeight = true;
		Ext.EventManager.onWindowResize(this.fireResize, this);
		this.renderTo = this.el;
	},

	fireResize : function(w, h){
		this.fireEvent('resize', this, w, h, w, h);
	}
});
Ext.reg('viewport', Ext.Viewport);

Ext.Panel = Ext.extend(Ext.Container, {












































	baseCls : 'x-panel',

	collapsedCls : 'x-panel-collapsed',

	maskDisabled : true,

	animCollapse : Ext.enableFx,

	headerAsText : true,

	buttonAlign : 'right',

	collapsed : false,

	collapseFirst : true,

	minButtonWidth : 75,


	elements : 'body',

	preventBodyReset : false,


	padding: undefined,


	resizeEvent: 'bodyresize',




	toolTarget : 'header',
	collapseEl : 'bwrap',
	slideAnchor : 't',
	disabledClass : '',


	deferHeight : true,

	expandDefaults: {
		duration : 0.25
	},

	collapseDefaults : {
		duration : 0.25
	},


	initComponent : function(){
		Ext.Panel.superclass.initComponent.call(this);

		this.addEvents(

			'bodyresize',

			'titlechange',

			'iconchange',

			'collapse',

			'expand',

			'beforecollapse',

			'beforeexpand',

			'beforeclose',

			'close',

			'activate',

			'deactivate'
			);

		if(this.unstyled){
			this.baseCls = 'x-plain';
		}


		this.toolbars = [];

		if(this.tbar){
			this.elements += ',tbar';
			this.topToolbar = this.createToolbar(this.tbar);
			this.tbar = null;

		}
		if(this.bbar){
			this.elements += ',bbar';
			this.bottomToolbar = this.createToolbar(this.bbar);
			this.bbar = null;
		}

		if(this.header === true){
			this.elements += ',header';
			this.header = null;
		}else if(this.headerCfg || (this.title && this.header !== false)){
			this.elements += ',header';
		}

		if(this.footerCfg || this.footer === true){
			this.elements += ',footer';
			this.footer = null;
		}

		if(this.buttons){
			this.fbar = this.buttons;
			this.buttons = null;
		}
		if(this.fbar){
			this.createFbar(this.fbar);
		}
		if(this.autoLoad){
			this.on('render', this.doAutoLoad, this, {
				delay:10
			});
		}
	},


	createFbar : function(fbar){
		var min = this.minButtonWidth;
		this.elements += ',footer';
		this.fbar = this.createToolbar(fbar, {
			buttonAlign: this.buttonAlign,
			toolbarCls: 'x-panel-fbar',
			enableOverflow: false,
			defaults: function(c){
				return {
					minWidth: c.minWidth || min
				};
			}
		});



		this.fbar.items.each(function(c){
			c.minWidth = c.minWidth || this.minButtonWidth;
		}, this);
		this.buttons = this.fbar.items.items;
	},


	createToolbar: function(tb, options){
		var result;

		if(Ext.isArray(tb)){
			tb = {
				items: tb
			};
		}
		result = tb.events ? Ext.apply(tb, options) : this.createComponent(Ext.apply({}, tb, options), 'toolbar');
		this.toolbars.push(result);
		return result;
	},


	createElement : function(name, pnode){
		if(this[name]){
			pnode.appendChild(this[name].dom);
			return;
		}

		if(name === 'bwrap' || this.elements.indexOf(name) != -1){
			if(this[name+'Cfg']){
				this[name] = Ext.fly(pnode).createChild(this[name+'Cfg']);
			}else{
				var el = document.createElement('div');
				el.className = this[name+'Cls'];
				this[name] = Ext.get(pnode.appendChild(el));
			}
			if(this[name+'CssClass']){
				this[name].addClass(this[name+'CssClass']);
			}
			if(this[name+'Style']){
				this[name].applyStyles(this[name+'Style']);
			}
		}
	},


	onRender : function(ct, position){
		Ext.Panel.superclass.onRender.call(this, ct, position);
		this.createClasses();

		var el = this.el,
		d = el.dom,
		bw,
		ts;


		if(this.collapsible && !this.hideCollapseTool){
			this.tools = this.tools ? this.tools.slice(0) : [];
			this.tools[this.collapseFirst?'unshift':'push']({
				id: 'toggle',
				handler : this.toggleCollapse,
				scope: this
			});
		}

		if(this.tools){
			ts = this.tools;
			this.elements += (this.header !== false) ? ',header' : '';
		}
		this.tools = {};

		el.addClass(this.baseCls);
		if(d.firstChild){
			this.header = el.down('.'+this.headerCls);
			this.bwrap = el.down('.'+this.bwrapCls);
			var cp = this.bwrap ? this.bwrap : el;
			this.tbar = cp.down('.'+this.tbarCls);
			this.body = cp.down('.'+this.bodyCls);
			this.bbar = cp.down('.'+this.bbarCls);
			this.footer = cp.down('.'+this.footerCls);
			this.fromMarkup = true;
		}
		if (this.preventBodyReset === true) {
			el.addClass('x-panel-reset');
		}
		if(this.cls){
			el.addClass(this.cls);
		}

		if(this.buttons){
			this.elements += ',footer';
		}




		if(this.frame){
			el.insertHtml('afterBegin', String.format(Ext.Element.boxMarkup, this.baseCls));

			this.createElement('header', d.firstChild.firstChild.firstChild);
			this.createElement('bwrap', d);


			bw = this.bwrap.dom;
			var ml = d.childNodes[1], bl = d.childNodes[2];
			bw.appendChild(ml);
			bw.appendChild(bl);

			var mc = bw.firstChild.firstChild.firstChild;
			this.createElement('tbar', mc);
			this.createElement('body', mc);
			this.createElement('bbar', mc);
			this.createElement('footer', bw.lastChild.firstChild.firstChild);

			if(!this.footer){
				this.bwrap.dom.lastChild.className += ' x-panel-nofooter';
			}

			this.ft = Ext.get(this.bwrap.dom.lastChild);
			this.mc = Ext.get(mc);
		}else{
			this.createElement('header', d);
			this.createElement('bwrap', d);


			bw = this.bwrap.dom;
			this.createElement('tbar', bw);
			this.createElement('body', bw);
			this.createElement('bbar', bw);
			this.createElement('footer', bw);

			if(!this.header){
				this.body.addClass(this.bodyCls + '-noheader');
				if(this.tbar){
					this.tbar.addClass(this.tbarCls + '-noheader');
				}
			}
		}

		if(Ext.isDefined(this.padding)){
			this.body.setStyle('padding', this.body.addUnits(this.padding));
		}

		if(this.border === false){
			this.el.addClass(this.baseCls + '-noborder');
			this.body.addClass(this.bodyCls + '-noborder');
			if(this.header){
				this.header.addClass(this.headerCls + '-noborder');
			}
			if(this.footer){
				this.footer.addClass(this.footerCls + '-noborder');
			}
			if(this.tbar){
				this.tbar.addClass(this.tbarCls + '-noborder');
			}
			if(this.bbar){
				this.bbar.addClass(this.bbarCls + '-noborder');
			}
		}

		if(this.bodyBorder === false){
			this.body.addClass(this.bodyCls + '-noborder');
		}

		this.bwrap.enableDisplayMode('block');

		if(this.header){
			this.header.unselectable();


			if(this.headerAsText){
				this.header.dom.innerHTML =
				'<span class="' + this.headerTextCls + '">'+this.header.dom.innerHTML+'</span>';

				if(this.iconCls){
					this.setIconClass(this.iconCls);
				}
			}
		}

		if(this.floating){
			this.makeFloating(this.floating);
		}

		if(this.collapsible && this.titleCollapse && this.header){
			this.mon(this.header, 'click', this.toggleCollapse, this);
			this.header.setStyle('cursor', 'pointer');
		}
		if(ts){
			this.addTool.apply(this, ts);
		}


		if(this.fbar){
			this.footer.addClass('x-panel-btns');
			this.fbar.ownerCt = this;
			this.fbar.render(this.footer);
			this.footer.createChild({
				cls:'x-clear'
			});
		}
		if(this.tbar && this.topToolbar){
			this.topToolbar.ownerCt = this;
			this.topToolbar.render(this.tbar);
		}
		if(this.bbar && this.bottomToolbar){
			this.bottomToolbar.ownerCt = this;
			this.bottomToolbar.render(this.bbar);
		}
	},


	setIconClass : function(cls){
		var old = this.iconCls;
		this.iconCls = cls;
		if(this.rendered && this.header){
			if(this.frame){
				this.header.addClass('x-panel-icon');
				this.header.replaceClass(old, this.iconCls);
			}else{
				var hd = this.header,
				img = hd.child('img.x-panel-inline-icon');
				if(img){
					Ext.fly(img).replaceClass(old, this.iconCls);
				}else{
					var hdspan = hd.child('span.' + this.headerTextCls);
					if (hdspan) {
						Ext.DomHelper.insertBefore(hdspan.dom, {
							tag:'img',
							alt: '',
							src: Ext.BLANK_IMAGE_URL,
							cls:'x-panel-inline-icon '+this.iconCls
						});
					}
				}
			}
		}
		this.fireEvent('iconchange', this, cls, old);
	},


	makeFloating : function(cfg){
		this.floating = true;
		this.el = new Ext.Layer(Ext.apply({}, cfg, {
			shadow: Ext.isDefined(this.shadow) ? this.shadow : 'sides',
			shadowOffset: this.shadowOffset,
			constrain:false,
			shim: this.shim === false ? false : undefined
		}), this.el);
	},


	getTopToolbar : function(){
		return this.topToolbar;
	},


	getBottomToolbar : function(){
		return this.bottomToolbar;
	},


	getFooterToolbar : function() {
		return this.fbar;
	},


	addButton : function(config, handler, scope){
		if(!this.fbar){
			this.createFbar([]);
		}
		if(handler){
			if(Ext.isString(config)){
				config = {
					text: config
				};
			}
			config = Ext.apply({
				handler: handler,
				scope: scope
			}, config);
		}
		return this.fbar.add(config);
	},


	addTool : function(){
		if(!this.rendered){
			if(!this.tools){
				this.tools = [];
			}
			Ext.each(arguments, function(arg){
				this.tools.push(arg);
			}, this);
			return;
		}

		if(!this[this.toolTarget]){
			return;
		}
		if(!this.toolTemplate){

			var tt = new Ext.Template(
				'<div class="x-tool x-tool-{id}">&#160;</div>'
				);
			tt.disableFormats = true;
			tt.compile();
			Ext.Panel.prototype.toolTemplate = tt;
		}
		for(var i = 0, a = arguments, len = a.length; i < len; i++) {
			var tc = a[i];
			if(!this.tools[tc.id]){
				var overCls = 'x-tool-'+tc.id+'-over';
				var t = this.toolTemplate.insertFirst(this[this.toolTarget], tc, true);
				this.tools[tc.id] = t;
				t.enableDisplayMode('block');
				this.mon(t, 'click',  this.createToolHandler(t, tc, overCls, this));
				if(tc.on){
					this.mon(t, tc.on);
				}
				if(tc.hidden){
					t.hide();
				}
				if(tc.qtip){
					if(Ext.isObject(tc.qtip)){
						Ext.QuickTips.register(Ext.apply({
							target: t.id
						}, tc.qtip));
					} else {
						t.dom.qtip = tc.qtip;
					}
				}
				t.addClassOnOver(overCls);
			}
		}
	},

	onLayout : function(shallow, force){
		Ext.Panel.superclass.onLayout.apply(this, arguments);
		if(this.hasLayout && this.toolbars.length > 0){
			Ext.each(this.toolbars, function(tb){
				tb.doLayout(undefined, force);
			});
			this.syncHeight();
		}
	},

	syncHeight : function(){
		var h = this.toolbarHeight,
		bd = this.body,
		lsh = this.lastSize.height,
		sz;

		if(this.autoHeight || !Ext.isDefined(lsh) || lsh == 'auto'){
			return;
		}


		if(h != this.getToolbarHeight()){
			h = Math.max(0, lsh - this.getFrameHeight());
			bd.setHeight(h);
			sz = bd.getSize();
			this.toolbarHeight = this.getToolbarHeight();
			this.onBodyResize(sz.width, sz.height);
		}
	},


	onShow : function(){
		if(this.floating){
			return this.el.show();
		}
		Ext.Panel.superclass.onShow.call(this);
	},


	onHide : function(){
		if(this.floating){
			return this.el.hide();
		}
		Ext.Panel.superclass.onHide.call(this);
	},


	createToolHandler : function(t, tc, overCls, panel){
		return function(e){
			t.removeClass(overCls);
			if(tc.stopEvent !== false){
				e.stopEvent();
			}
			if(tc.handler){
				tc.handler.call(tc.scope || t, e, t, panel, tc);
			}
		};
	},


	afterRender : function(){
		if(this.floating && !this.hidden){
			this.el.show();
		}
		if(this.title){
			this.setTitle(this.title);
		}
		Ext.Panel.superclass.afterRender.call(this);
		if (this.collapsed) {
			this.collapsed = false;
			this.collapse(false);
		}
		this.initEvents();
	},


	getKeyMap : function(){
		if(!this.keyMap){
			this.keyMap = new Ext.KeyMap(this.el, this.keys);
		}
		return this.keyMap;
	},


	initEvents : function(){
		if(this.keys){
			this.getKeyMap();
		}
		if(this.draggable){
			this.initDraggable();
		}
		if(this.toolbars.length > 0){
			Ext.each(this.toolbars, function(tb){
				tb.doLayout();
				tb.on({
					scope: this,
					afterlayout: this.syncHeight,
					remove: this.syncHeight
				});
			}, this);
			this.syncHeight();
		}

	},


	initDraggable : function(){

		this.dd = new Ext.Panel.DD(this, Ext.isBoolean(this.draggable) ? null : this.draggable);
	},


	beforeEffect : function(anim){
		if(this.floating){
			this.el.beforeAction();
		}
		if(anim !== false){
			this.el.addClass('x-panel-animated');
		}
	},


	afterEffect : function(anim){
		this.syncShadow();
		this.el.removeClass('x-panel-animated');
	},


	createEffect : function(a, cb, scope){
		var o = {
			scope:scope,
			block:true
		};
		if(a === true){
			o.callback = cb;
			return o;
		}else if(!a.callback){
			o.callback = cb;
		}else {
			o.callback = function(){
				cb.call(scope);
				Ext.callback(a.callback, a.scope);
			};
		}
		return Ext.applyIf(o, a);
	},


	collapse : function(animate){
		if(this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforecollapse', this, animate) === false){
			return;
		}
		var doAnim = animate === true || (animate !== false && this.animCollapse);
		this.beforeEffect(doAnim);
		this.onCollapse(doAnim, animate);
		return this;
	},


	onCollapse : function(doAnim, animArg){
		if(doAnim){
			this[this.collapseEl].slideOut(this.slideAnchor,
				Ext.apply(this.createEffect(animArg||true, this.afterCollapse, this),
					this.collapseDefaults));
		}else{
			this[this.collapseEl].hide(this.hideMode);
			this.afterCollapse(false);
		}
	},


	afterCollapse : function(anim){
		this.collapsed = true;
		this.el.addClass(this.collapsedCls);
		if(anim !== false){
			this[this.collapseEl].hide(this.hideMode);
		}
		this.afterEffect(anim);


		this.cascade(function(c) {
			if (c.lastSize) {
				c.lastSize = {
					width: undefined,
					height: undefined
				};
			}
		});
		this.fireEvent('collapse', this);
	},


	expand : function(animate){
		if(!this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforeexpand', this, animate) === false){
			return;
		}
		var doAnim = animate === true || (animate !== false && this.animCollapse);
		this.el.removeClass(this.collapsedCls);
		this.beforeEffect(doAnim);
		this.onExpand(doAnim, animate);
		return this;
	},


	onExpand : function(doAnim, animArg){
		if(doAnim){
			this[this.collapseEl].slideIn(this.slideAnchor,
				Ext.apply(this.createEffect(animArg||true, this.afterExpand, this),
					this.expandDefaults));
		}else{
			this[this.collapseEl].show(this.hideMode);
			this.afterExpand(false);
		}
	},


	afterExpand : function(anim){
		this.collapsed = false;
		if(anim !== false){
			this[this.collapseEl].show(this.hideMode);
		}
		this.afterEffect(anim);
		if (this.deferLayout) {
			delete this.deferLayout;
			this.doLayout(true);
		}
		this.fireEvent('expand', this);
	},


	toggleCollapse : function(animate){
		this[this.collapsed ? 'expand' : 'collapse'](animate);
		return this;
	},


	onDisable : function(){
		if(this.rendered && this.maskDisabled){
			this.el.mask();
		}
		Ext.Panel.superclass.onDisable.call(this);
	},


	onEnable : function(){
		if(this.rendered && this.maskDisabled){
			this.el.unmask();
		}
		Ext.Panel.superclass.onEnable.call(this);
	},


	onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
		var w = adjWidth,
		h = adjHeight;

		if(Ext.isDefined(w) || Ext.isDefined(h)){
			if(!this.collapsed){




				if(Ext.isNumber(w)){
					this.body.setWidth(w = this.adjustBodyWidth(w - this.getFrameWidth()));
				} else if (w == 'auto') {
					w = this.body.setWidth('auto').dom.offsetWidth;
				} else {
					w = this.body.dom.offsetWidth;
				}

				if(this.tbar){
					this.tbar.setWidth(w);
					if(this.topToolbar){
						this.topToolbar.setSize(w);
					}
				}
				if(this.bbar){
					this.bbar.setWidth(w);
					if(this.bottomToolbar){
						this.bottomToolbar.setSize(w);

						if (Ext.isIE) {
							this.bbar.setStyle('position', 'static');
							this.bbar.setStyle('position', '');
						}
					}
				}
				if(this.footer){
					this.footer.setWidth(w);
					if(this.fbar){
						this.fbar.setSize(Ext.isIE ? (w - this.footer.getFrameWidth('lr')) : 'auto');
					}
				}


				if(Ext.isNumber(h)){
					h = Math.max(0, h - this.getFrameHeight());

					this.body.setHeight(h);
				}else if(h == 'auto'){
					this.body.setHeight(h);
				}

				if(this.disabled && this.el._mask){
					this.el._mask.setSize(this.el.dom.clientWidth, this.el.getHeight());
				}
			}else{

				this.queuedBodySize = {
					width: w,
					height: h
				};
				if(!this.queuedExpand && this.allowQueuedExpand !== false){
					this.queuedExpand = true;
					this.on('expand', function(){
						delete this.queuedExpand;
						this.onResize(this.queuedBodySize.width, this.queuedBodySize.height);
					}, this, {
						single:true
					});
				}
			}
			this.onBodyResize(w, h);
		}
		this.syncShadow();
		Ext.Panel.superclass.onResize.call(this, adjWidth, adjHeight, rawWidth, rawHeight);

	},


	onBodyResize: function(w, h){
		this.fireEvent('bodyresize', this, w, h);
	},


	getToolbarHeight: function(){
		var h = 0;
		if(this.rendered){
			Ext.each(this.toolbars, function(tb){
				h += tb.getHeight();
			}, this);
		}
		return h;
	},


	adjustBodyHeight : function(h){
		return h;
	},


	adjustBodyWidth : function(w){
		return w;
	},


	onPosition : function(){
		this.syncShadow();
	},


	getFrameWidth : function(){
		var w = this.el.getFrameWidth('lr') + this.bwrap.getFrameWidth('lr');

		if(this.frame){
			var l = this.bwrap.dom.firstChild;
			w += (Ext.fly(l).getFrameWidth('l') + Ext.fly(l.firstChild).getFrameWidth('r'));
			w += this.mc.getFrameWidth('lr');
		}
		return w;
	},


	getFrameHeight : function() {
		var h  = this.el.getFrameWidth('tb') + this.bwrap.getFrameWidth('tb');
		h += (this.tbar ? this.tbar.getHeight() : 0) +
		(this.bbar ? this.bbar.getHeight() : 0);

		if(this.frame){
			h += this.el.dom.firstChild.offsetHeight + this.ft.dom.offsetHeight + this.mc.getFrameWidth('tb');
		}else{
			h += (this.header ? this.header.getHeight() : 0) +
			(this.footer ? this.footer.getHeight() : 0);
		}
		return h;
	},


	getInnerWidth : function(){
		return this.getSize().width - this.getFrameWidth();
	},


	getInnerHeight : function(){
		return this.body.getHeight();

	},


	syncShadow : function(){
		if(this.floating){
			this.el.sync(true);
		}
	},


	getLayoutTarget : function(){
		return this.body;
	},


	getContentTarget : function(){
		return this.body;
	},


	setTitle : function(title, iconCls){
		this.title = title;
		if(this.header && this.headerAsText){
			this.header.child('span').update(title);
		}
		if(iconCls){
			this.setIconClass(iconCls);
		}
		this.fireEvent('titlechange', this, title);
		return this;
	},


	getUpdater : function(){
		return this.body.getUpdater();
	},


	load : function(){
		var um = this.body.getUpdater();
		um.update.apply(um, arguments);
		return this;
	},


	beforeDestroy : function(){
		Ext.Panel.superclass.beforeDestroy.call(this);
		if(this.header){
			this.header.removeAllListeners();
		}
		if(this.tools){
			for(var k in this.tools){
				Ext.destroy(this.tools[k]);
			}
		}
		if(this.toolbars.length > 0){
			Ext.each(this.toolbars, function(tb){
				tb.un('afterlayout', this.syncHeight, this);
				tb.un('remove', this.syncHeight, this);
			}, this);
		}
		if(Ext.isArray(this.buttons)){
			while(this.buttons.length) {
				Ext.destroy(this.buttons[0]);
			}
		}
		if(this.rendered){
			Ext.destroy(
				this.ft,
				this.header,
				this.footer,
				this.tbar,
				this.bbar,
				this.body,
				this.mc,
				this.bwrap,
				this.dd
				);
			if (this.fbar) {
				Ext.destroy(
					this.fbar,
					this.fbar.el
					);
			}
		}
		Ext.destroy(this.toolbars);
	},


	createClasses : function(){
		this.headerCls = this.baseCls + '-header';
		this.headerTextCls = this.baseCls + '-header-text';
		this.bwrapCls = this.baseCls + '-bwrap';
		this.tbarCls = this.baseCls + '-tbar';
		this.bodyCls = this.baseCls + '-body';
		this.bbarCls = this.baseCls + '-bbar';
		this.footerCls = this.baseCls + '-footer';
	},


	createGhost : function(cls, useShim, appendTo){
		var el = document.createElement('div');
		el.className = 'x-panel-ghost ' + (cls ? cls : '');
		if(this.header){
			el.appendChild(this.el.dom.firstChild.cloneNode(true));
		}
		Ext.fly(el.appendChild(document.createElement('ul'))).setHeight(this.bwrap.getHeight());
		el.style.width = this.el.dom.offsetWidth + 'px';
		;
		if(!appendTo){
			this.container.dom.appendChild(el);
		}else{
			Ext.getDom(appendTo).appendChild(el);
		}
		if(useShim !== false && this.el.useShim !== false){
			var layer = new Ext.Layer({
				shadow:false,
				useDisplay:true,
				constrain:false
			}, el);
			layer.show();
			return layer;
		}else{
			return new Ext.Element(el);
		}
	},


	doAutoLoad : function(){
		var u = this.body.getUpdater();
		if(this.renderer){
			u.setRenderer(this.renderer);
		}
		u.update(Ext.isObject(this.autoLoad) ? this.autoLoad : {
			url: this.autoLoad
			});
	},


	getTool : function(id) {
		return this.tools[id];
	}


});
Ext.reg('panel', Ext.Panel);

Ext.Editor = function(field, config){
	if(field.field){
		this.field = Ext.create(field.field, 'textfield');
		config = Ext.apply({}, field);
		delete config.field;
	}else{
		this.field = field;
	}
	Ext.Editor.superclass.constructor.call(this, config);
};

Ext.extend(Ext.Editor, Ext.Component, {


	allowBlur: true,





	value : "",

	alignment: "c-c?",

	offsets: [0, 0],

	shadow : "frame",

	constrain : false,

	swallowKeys : true,

	completeOnEnter : true,

	cancelOnEsc : true,

	updateEl : false,

	initComponent : function(){
		Ext.Editor.superclass.initComponent.call(this);
		this.addEvents(

			"beforestartedit",

			"startedit",

			"beforecomplete",

			"complete",

			"canceledit",

			"specialkey"
			);
	},


	onRender : function(ct, position){
		this.el = new Ext.Layer({
			shadow: this.shadow,
			cls: "x-editor",
			parentEl : ct,
			shim : this.shim,
			shadowOffset: this.shadowOffset || 4,
			id: this.id,
			constrain: this.constrain
		});
		if(this.zIndex){
			this.el.setZIndex(this.zIndex);
		}
		this.el.setStyle("overflow", Ext.isGecko ? "auto" : "hidden");
		if(this.field.msgTarget != 'title'){
			this.field.msgTarget = 'qtip';
		}
		this.field.inEditor = true;
		this.mon(this.field, {
			scope: this,
			blur: this.onBlur,
			specialkey: this.onSpecialKey
		});
		if(this.field.grow){
			this.mon(this.field, "autosize", this.el.sync,  this.el, {
				delay:1
			});
		}
		this.field.render(this.el).show();
		this.field.getEl().dom.name = '';
		if(this.swallowKeys){
			this.field.el.swallowEvent([
				'keypress',
				'keydown'
				]);
		}
	},


	onSpecialKey : function(field, e){
		var key = e.getKey(),
		complete = this.completeOnEnter && key == e.ENTER,
		cancel = this.cancelOnEsc && key == e.ESC;
		if(complete || cancel){
			e.stopEvent();
			if(complete){
				this.completeEdit();
			}else{
				this.cancelEdit();
			}
			if(field.triggerBlur){
				field.triggerBlur();
			}
		}
		this.fireEvent('specialkey', field, e);
	},


	startEdit : function(el, value){
		if(this.editing){
			this.completeEdit();
		}
		this.boundEl = Ext.get(el);
		var v = value !== undefined ? value : this.boundEl.dom.innerHTML;
		if(!this.rendered){
			this.render(this.parentEl || document.body);
		}
		if(this.fireEvent("beforestartedit", this, this.boundEl, v) !== false){
			this.startValue = v;
			this.field.reset();
			this.field.setValue(v);
			this.realign(true);
			this.editing = true;
			this.show();
		}
	},


	doAutoSize : function(){
		if(this.autoSize){
			var sz = this.boundEl.getSize(),
			fs = this.field.getSize();

			switch(this.autoSize){
				case "width":
					this.setSize(sz.width, fs.height);
					break;
				case "height":
					this.setSize(fs.width, sz.height);
					break;
				case "none":
					this.setSize(fs.width, fs.height);
					break;
				default:
					this.setSize(sz.width, sz.height);
			}
		}
	},


	setSize : function(w, h){
		delete this.field.lastSize;
		this.field.setSize(w, h);
		if(this.el){

			if(Ext.isGecko2 || Ext.isOpera || (Ext.isIE7 && Ext.isStrict)){

				this.el.setSize(w, h);
			}
			this.el.sync();
		}
	},


	realign : function(autoSize){
		if(autoSize === true){
			this.doAutoSize();
		}
		this.el.alignTo(this.boundEl, this.alignment, this.offsets);
	},


	completeEdit : function(remainVisible){
		if(!this.editing){
			return;
		}

		if (this.field.assertValue) {
			this.field.assertValue();
		}
		var v = this.getValue();
		if(!this.field.isValid()){
			if(this.revertInvalid !== false){
				this.cancelEdit(remainVisible);
			}
			return;
		}
		if(String(v) === String(this.startValue) && this.ignoreNoChange){
			this.hideEdit(remainVisible);
			return;
		}
		if(this.fireEvent("beforecomplete", this, v, this.startValue) !== false){
			v = this.getValue();
			if(this.updateEl && this.boundEl){
				this.boundEl.update(v);
			}
			this.hideEdit(remainVisible);
			this.fireEvent("complete", this, v, this.startValue);
		}
	},


	onShow : function(){
		this.el.show();
		if(this.hideEl !== false){
			this.boundEl.hide();
		}
		this.field.show().focus(false, true);
		this.fireEvent("startedit", this.boundEl, this.startValue);
	},


	cancelEdit : function(remainVisible){
		if(this.editing){
			var v = this.getValue();
			this.setValue(this.startValue);
			this.hideEdit(remainVisible);
			this.fireEvent("canceledit", this, v, this.startValue);
		}
	},


	hideEdit: function(remainVisible){
		if(remainVisible !== true){
			this.editing = false;
			this.hide();
		}
	},


	onBlur : function(){

		if(this.allowBlur === true && this.editing && this.selectSameEditor !== true){
			this.completeEdit();
		}
	},


	onHide : function(){
		if(this.editing){
			this.completeEdit();
			return;
		}
		this.field.blur();
		if(this.field.collapse){
			this.field.collapse();
		}
		this.el.hide();
		if(this.hideEl !== false){
			this.boundEl.show();
		}
	},


	setValue : function(v){
		this.field.setValue(v);
	},


	getValue : function(){
		return this.field.getValue();
	},

	beforeDestroy : function(){
		Ext.destroyMembers(this, 'field');

		delete this.parentEl;
		delete this.boundEl;
	}
});
Ext.reg('editor', Ext.Editor);

Ext.ColorPalette = Ext.extend(Ext.Component, {


	itemCls : 'x-color-palette',

	value : null,

	clickEvent :'click',

	ctype : 'Ext.ColorPalette',


	allowReselect : false,


	colors : [
	'000000', '993300', '333300', '003300', '003366', '000080', '333399', '333333',
	'800000', 'FF6600', '808000', '008000', '008080', '0000FF', '666699', '808080',
	'FF0000', 'FF9900', '99CC00', '339966', '33CCCC', '3366FF', '800080', '969696',
	'FF00FF', 'FFCC00', 'FFFF00', '00FF00', '00FFFF', '00CCFF', '993366', 'C0C0C0',
	'FF99CC', 'FFCC99', 'FFFF99', 'CCFFCC', 'CCFFFF', '99CCFF', 'CC99FF', 'FFFFFF'
	],





	initComponent : function(){
		Ext.ColorPalette.superclass.initComponent.call(this);
		this.addEvents(

			'select'
			);

		if(this.handler){
			this.on('select', this.handler, this.scope, true);
		}
	},


	onRender : function(container, position){
		this.autoEl = {
			tag: 'div',
			cls: this.itemCls
		};
		Ext.ColorPalette.superclass.onRender.call(this, container, position);
		var t = this.tpl || new Ext.XTemplate(
			'<tpl for="."><a href="#" class="color-{.}" hidefocus="on"><em><span style="background:#{.}" unselectable="on">&#160;</span></em></a></tpl>'
			);
		t.overwrite(this.el, this.colors);
		this.mon(this.el, this.clickEvent, this.handleClick, this, {
			delegate: 'a'
		});
		if(this.clickEvent != 'click'){
			this.mon(this.el, 'click', Ext.emptyFn, this, {
				delegate: 'a',
				preventDefault: true
			});
		}
	},


	afterRender : function(){
		Ext.ColorPalette.superclass.afterRender.call(this);
		if(this.value){
			var s = this.value;
			this.value = null;
			this.select(s, true);
		}
	},


	handleClick : function(e, t){
		e.preventDefault();
		if(!this.disabled){
			var c = t.className.match(/(?:^|\s)color-(.{6})(?:\s|$)/)[1];
			this.select(c.toUpperCase());
		}
	},


	select : function(color, suppressEvent){
		color = color.replace('#', '');
		if(color != this.value || this.allowReselect){
			var el = this.el;
			if(this.value){
				el.child('a.color-'+this.value).removeClass('x-color-palette-sel');
			}
			el.child('a.color-'+color).addClass('x-color-palette-sel');
			this.value = color;
			if(suppressEvent !== true){
				this.fireEvent('select', this, color);
			}
		}
	}


});
Ext.reg('colorpalette', Ext.ColorPalette);
Ext.DatePicker = Ext.extend(Ext.BoxComponent, {

	todayText : 'Today',

	okText : '&#160;OK&#160;',

	cancelText : 'Cancel',



	todayTip : '{0} (Spacebar)',

	minText : 'This date is before the minimum date',

	maxText : 'This date is after the maximum date',

	format : 'm/d/y',

	disabledDaysText : 'Disabled',

	disabledDatesText : 'Disabled',

	monthNames : Date.monthNames,

	dayNames : Date.dayNames,

	nextText : 'Next Month (Control+Right)',

	prevText : 'Previous Month (Control+Left)',

	monthYearText : 'Choose a month (Control+Up/Down to move years)',

	startDay : 0,

	showToday : true,








	focusOnSelect: true,



	initHour: 12,


	initComponent : function(){
		Ext.DatePicker.superclass.initComponent.call(this);

		this.value = this.value ?
		this.value.clearTime(true) : new Date().clearTime();

		this.addEvents(

			'select'
			);

		if(this.handler){
			this.on('select', this.handler,  this.scope || this);
		}

		this.initDisabledDays();
	},


	initDisabledDays : function(){
		if(!this.disabledDatesRE && this.disabledDates){
			var dd = this.disabledDates,
			len = dd.length - 1,
			re = '(?:';

			Ext.each(dd, function(d, i){
				re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i];
				if(i != len){
					re += '|';
				}
			}, this);
			this.disabledDatesRE = new RegExp(re + ')');
		}
	},


	setDisabledDates : function(dd){
		if(Ext.isArray(dd)){
			this.disabledDates = dd;
			this.disabledDatesRE = null;
		}else{
			this.disabledDatesRE = dd;
		}
		this.initDisabledDays();
		this.update(this.value, true);
	},


	setDisabledDays : function(dd){
		this.disabledDays = dd;
		this.update(this.value, true);
	},


	setMinDate : function(dt){
		this.minDate = dt;
		this.update(this.value, true);
	},


	setMaxDate : function(dt){
		this.maxDate = dt;
		this.update(this.value, true);
	},


	setValue : function(value){
		this.value = value.clearTime(true);
		this.update(this.value);
	},


	getValue : function(){
		return this.value;
	},


	focus : function(){
		this.update(this.activeDate);
	},


	onEnable: function(initial){
		Ext.DatePicker.superclass.onEnable.call(this);
		this.doDisabled(false);
		this.update(initial ? this.value : this.activeDate);
		if(Ext.isIE){
			this.el.repaint();
		}

	},


	onDisable : function(){
		Ext.DatePicker.superclass.onDisable.call(this);
		this.doDisabled(true);
		if(Ext.isIE && !Ext.isIE8){

			Ext.each([].concat(this.textNodes, this.el.query('th span')), function(el){
				Ext.fly(el).repaint();
			});
		}
	},


	doDisabled : function(disabled){
		this.keyNav.setDisabled(disabled);
		this.prevRepeater.setDisabled(disabled);
		this.nextRepeater.setDisabled(disabled);
		if(this.showToday){
			this.todayKeyListener.setDisabled(disabled);
			this.todayBtn.setDisabled(disabled);
		}
	},


	onRender : function(container, position){
		var m = [
		'<table cellspacing="0">',
		'<tr><td class="x-date-left"><a href="#" title="', this.prevText ,'">&#160;</a></td><td class="x-date-middle" align="center"></td><td class="x-date-right"><a href="#" title="', this.nextText ,'">&#160;</a></td></tr>',
		'<tr><td colspan="3"><table class="x-date-inner" cellspacing="0"><thead><tr>'],
		dn = this.dayNames,
		i;
		for(i = 0; i < 7; i++){
			var d = this.startDay+i;
			if(d > 6){
				d = d-7;
			}
			m.push('<th><span>', dn[d].substr(0,1), '</span></th>');
		}
		m[m.length] = '</tr></thead><tbody><tr>';
		for(i = 0; i < 42; i++) {
			if(i % 7 === 0 && i !== 0){
				m[m.length] = '</tr><tr>';
			}
			m[m.length] = '<td><a href="#" hidefocus="on" class="x-date-date" tabIndex="1"><em><span></span></em></a></td>';
		}
		m.push('</tr></tbody></table></td></tr>',
			this.showToday ? '<tr><td colspan="3" class="x-date-bottom" align="center"></td></tr>' : '',
			'</table><div class="x-date-mp"></div>');

		var el = document.createElement('div');
		el.className = 'x-date-picker';
		el.innerHTML = m.join('');

		container.dom.insertBefore(el, position);

		this.el = Ext.get(el);
		this.eventEl = Ext.get(el.firstChild);

		this.prevRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-left a'), {
			handler: this.showPrevMonth,
			scope: this,
			preventDefault:true,
			stopDefault:true
		});

		this.nextRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-right a'), {
			handler: this.showNextMonth,
			scope: this,
			preventDefault:true,
			stopDefault:true
		});

		this.monthPicker = this.el.down('div.x-date-mp');
		this.monthPicker.enableDisplayMode('block');

		this.keyNav = new Ext.KeyNav(this.eventEl, {
			'left' : function(e){
				if(e.ctrlKey){
					this.showPrevMonth();
				}else{
					this.update(this.activeDate.add('d', -1));
				}
			},

			'right' : function(e){
				if(e.ctrlKey){
					this.showNextMonth();
				}else{
					this.update(this.activeDate.add('d', 1));
				}
			},

			'up' : function(e){
				if(e.ctrlKey){
					this.showNextYear();
				}else{
					this.update(this.activeDate.add('d', -7));
				}
			},

			'down' : function(e){
				if(e.ctrlKey){
					this.showPrevYear();
				}else{
					this.update(this.activeDate.add('d', 7));
				}
			},

			'pageUp' : function(e){
				this.showNextMonth();
			},

			'pageDown' : function(e){
				this.showPrevMonth();
			},

			'enter' : function(e){
				e.stopPropagation();
				return true;
			},

			scope : this
		});

		this.el.unselectable();

		this.cells = this.el.select('table.x-date-inner tbody td');
		this.textNodes = this.el.query('table.x-date-inner tbody span');

		this.mbtn = new Ext.Button({
			text: '&#160;',
			tooltip: this.monthYearText,
			renderTo: this.el.child('td.x-date-middle', true)
		});
		this.mbtn.el.child('em').addClass('x-btn-arrow');

		if(this.showToday){
			this.todayKeyListener = this.eventEl.addKeyListener(Ext.EventObject.SPACE, this.selectToday,  this);
			var today = (new Date()).dateFormat(this.format);
			this.todayBtn = new Ext.Button({
				renderTo: this.el.child('td.x-date-bottom', true),
				text: String.format(this.todayText, today),
				tooltip: String.format(this.todayTip, today),
				handler: this.selectToday,
				scope: this
			});
		}
		this.mon(this.eventEl, 'mousewheel', this.handleMouseWheel, this);
		this.mon(this.eventEl, 'click', this.handleDateClick,  this, {
			delegate: 'a.x-date-date'
		});
		this.mon(this.mbtn, 'click', this.showMonthPicker, this);
		this.onEnable(true);
	},


	createMonthPicker : function(){
		if(!this.monthPicker.dom.firstChild){
			var buf = ['<table border="0" cellspacing="0">'];
			for(var i = 0; i < 6; i++){
				buf.push(
					'<tr><td class="x-date-mp-month"><a href="#">', Date.getShortMonthName(i), '</a></td>',
					'<td class="x-date-mp-month x-date-mp-sep"><a href="#">', Date.getShortMonthName(i + 6), '</a></td>',
					i === 0 ?
					'<td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-prev"></a></td><td class="x-date-mp-ybtn" align="center"><a class="x-date-mp-next"></a></td></tr>' :
					'<td class="x-date-mp-year"><a href="#"></a></td><td class="x-date-mp-year"><a href="#"></a></td></tr>'
					);
			}
			buf.push(
				'<tr class="x-date-mp-btns"><td colspan="4"><button type="button" class="x-date-mp-ok">',
				this.okText,
				'</button><button type="button" class="x-date-mp-cancel">',
				this.cancelText,
				'</button></td></tr>',
				'</table>'
				);
			this.monthPicker.update(buf.join(''));

			this.mon(this.monthPicker, 'click', this.onMonthClick, this);
			this.mon(this.monthPicker, 'dblclick', this.onMonthDblClick, this);

			this.mpMonths = this.monthPicker.select('td.x-date-mp-month');
			this.mpYears = this.monthPicker.select('td.x-date-mp-year');

			this.mpMonths.each(function(m, a, i){
				i += 1;
				if((i%2) === 0){
					m.dom.xmonth = 5 + Math.round(i * 0.5);
				}else{
					m.dom.xmonth = Math.round((i-1) * 0.5);
				}
			});
		}
	},


	showMonthPicker : function(){
		if(!this.disabled){
			this.createMonthPicker();
			var size = this.el.getSize();
			this.monthPicker.setSize(size);
			this.monthPicker.child('table').setSize(size);

			this.mpSelMonth = (this.activeDate || this.value).getMonth();
			this.updateMPMonth(this.mpSelMonth);
			this.mpSelYear = (this.activeDate || this.value).getFullYear();
			this.updateMPYear(this.mpSelYear);

			this.monthPicker.slideIn('t', {
				duration:0.2
			});
		}
	},


	updateMPYear : function(y){
		this.mpyear = y;
		var ys = this.mpYears.elements;
		for(var i = 1; i <= 10; i++){
			var td = ys[i-1], y2;
			if((i%2) === 0){
				y2 = y + Math.round(i * 0.5);
				td.firstChild.innerHTML = y2;
				td.xyear = y2;
			}else{
				y2 = y - (5-Math.round(i * 0.5));
				td.firstChild.innerHTML = y2;
				td.xyear = y2;
			}
			this.mpYears.item(i-1)[y2 == this.mpSelYear ? 'addClass' : 'removeClass']('x-date-mp-sel');
		}
	},


	updateMPMonth : function(sm){
		this.mpMonths.each(function(m, a, i){
			m[m.dom.xmonth == sm ? 'addClass' : 'removeClass']('x-date-mp-sel');
		});
	},


	selectMPMonth : function(m){

	},


	onMonthClick : function(e, t){
		e.stopEvent();
		var el = new Ext.Element(t), pn;
		if(el.is('button.x-date-mp-cancel')){
			this.hideMonthPicker();
		}
		else if(el.is('button.x-date-mp-ok')){
			var d = new Date(this.mpSelYear, this.mpSelMonth, (this.activeDate || this.value).getDate());
			if(d.getMonth() != this.mpSelMonth){

				d = new Date(this.mpSelYear, this.mpSelMonth, 1).getLastDateOfMonth();
			}
			this.update(d);
			this.hideMonthPicker();
		}
		else if((pn = el.up('td.x-date-mp-month', 2))){
			this.mpMonths.removeClass('x-date-mp-sel');
			pn.addClass('x-date-mp-sel');
			this.mpSelMonth = pn.dom.xmonth;
		}
		else if((pn = el.up('td.x-date-mp-year', 2))){
			this.mpYears.removeClass('x-date-mp-sel');
			pn.addClass('x-date-mp-sel');
			this.mpSelYear = pn.dom.xyear;
		}
		else if(el.is('a.x-date-mp-prev')){
			this.updateMPYear(this.mpyear-10);
		}
		else if(el.is('a.x-date-mp-next')){
			this.updateMPYear(this.mpyear+10);
		}
	},


	onMonthDblClick : function(e, t){
		e.stopEvent();
		var el = new Ext.Element(t), pn;
		if((pn = el.up('td.x-date-mp-month', 2))){
			this.update(new Date(this.mpSelYear, pn.dom.xmonth, (this.activeDate || this.value).getDate()));
			this.hideMonthPicker();
		}
		else if((pn = el.up('td.x-date-mp-year', 2))){
			this.update(new Date(pn.dom.xyear, this.mpSelMonth, (this.activeDate || this.value).getDate()));
			this.hideMonthPicker();
		}
	},


	hideMonthPicker : function(disableAnim){
		if(this.monthPicker){
			if(disableAnim === true){
				this.monthPicker.hide();
			}else{
				this.monthPicker.slideOut('t', {
					duration:0.2
				});
			}
		}
	},


	showPrevMonth : function(e){
		this.update(this.activeDate.add('mo', -1));
	},


	showNextMonth : function(e){
		this.update(this.activeDate.add('mo', 1));
	},


	showPrevYear : function(){
		this.update(this.activeDate.add('y', -1));
	},


	showNextYear : function(){
		this.update(this.activeDate.add('y', 1));
	},


	handleMouseWheel : function(e){
		e.stopEvent();
		if(!this.disabled){
			var delta = e.getWheelDelta();
			if(delta > 0){
				this.showPrevMonth();
			} else if(delta < 0){
				this.showNextMonth();
			}
		}
	},


	handleDateClick : function(e, t){
		e.stopEvent();
		if(!this.disabled && t.dateValue && !Ext.fly(t.parentNode).hasClass('x-date-disabled')){
			this.cancelFocus = this.focusOnSelect === false;
			this.setValue(new Date(t.dateValue));
			delete this.cancelFocus;
			this.fireEvent('select', this, this.value);
		}
	},


	selectToday : function(){
		if(this.todayBtn && !this.todayBtn.disabled){
			this.setValue(new Date().clearTime());
			this.fireEvent('select', this, this.value);
		}
	},


	update : function(date, forceRefresh){
		if(this.rendered){
			var vd = this.activeDate, vis = this.isVisible();
			this.activeDate = date;
			if(!forceRefresh && vd && this.el){
				var t = date.getTime();
				if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
					this.cells.removeClass('x-date-selected');
					this.cells.each(function(c){
						if(c.dom.firstChild.dateValue == t){
							c.addClass('x-date-selected');
							if(vis && !this.cancelFocus){
								Ext.fly(c.dom.firstChild).focus(50);
							}
							return false;
						}
					}, this);
					return;
				}
			}
			var days = date.getDaysInMonth(),
			firstOfMonth = date.getFirstDateOfMonth(),
			startingPos = firstOfMonth.getDay()-this.startDay;

			if(startingPos < 0){
				startingPos += 7;
			}
			days += startingPos;

			var pm = date.add('mo', -1),
			prevStart = pm.getDaysInMonth()-startingPos,
			cells = this.cells.elements,
			textEls = this.textNodes,

			d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart, this.initHour)),
			today = new Date().clearTime().getTime(),
			sel = date.clearTime(true).getTime(),
			min = this.minDate ? this.minDate.clearTime(true) : Number.NEGATIVE_INFINITY,
			max = this.maxDate ? this.maxDate.clearTime(true) : Number.POSITIVE_INFINITY,
			ddMatch = this.disabledDatesRE,
			ddText = this.disabledDatesText,
			ddays = this.disabledDays ? this.disabledDays.join('') : false,
			ddaysText = this.disabledDaysText,
			format = this.format;

			if(this.showToday){
				var td = new Date().clearTime(),
				disable = (td < min || td > max ||
					(ddMatch && format && ddMatch.test(td.dateFormat(format))) ||
					(ddays && ddays.indexOf(td.getDay()) != -1));

				if(!this.disabled){
					this.todayBtn.setDisabled(disable);
					this.todayKeyListener[disable ? 'disable' : 'enable']();
				}
			}

			var setCellClass = function(cal, cell){
				cell.title = '';
				var t = d.clearTime(true).getTime();
				cell.firstChild.dateValue = t;
				if(t == today){
					cell.className += ' x-date-today';
					cell.title = cal.todayText;
				}
				if(t == sel){
					cell.className += ' x-date-selected';
					if(vis){
						Ext.fly(cell.firstChild).focus(50);
					}
				}

				if(t < min) {
					cell.className = ' x-date-disabled';
					cell.title = cal.minText;
					return;
				}
				if(t > max) {
					cell.className = ' x-date-disabled';
					cell.title = cal.maxText;
					return;
				}
				if(ddays){
					if(ddays.indexOf(d.getDay()) != -1){
						cell.title = ddaysText;
						cell.className = ' x-date-disabled';
					}
				}
				if(ddMatch && format){
					var fvalue = d.dateFormat(format);
					if(ddMatch.test(fvalue)){
						cell.title = ddText.replace('%0', fvalue);
						cell.className = ' x-date-disabled';
					}
				}
			};

			var i = 0;
			for(; i < startingPos; i++) {
				textEls[i].innerHTML = (++prevStart);
				d.setDate(d.getDate()+1);
				cells[i].className = 'x-date-prevday';
				setCellClass(this, cells[i]);
			}
			for(; i < days; i++){
				var intDay = i - startingPos + 1;
				textEls[i].innerHTML = (intDay);
				d.setDate(d.getDate()+1);
				cells[i].className = 'x-date-active';
				setCellClass(this, cells[i]);
			}
			var extraDays = 0;
			for(; i < 42; i++) {
				textEls[i].innerHTML = (++extraDays);
				d.setDate(d.getDate()+1);
				cells[i].className = 'x-date-nextday';
				setCellClass(this, cells[i]);
			}

			this.mbtn.setText(this.monthNames[date.getMonth()] + ' ' + date.getFullYear());

			if(!this.internalRender){
				var main = this.el.dom.firstChild,
				w = main.offsetWidth;
				this.el.setWidth(w + this.el.getBorderWidth('lr'));
				Ext.fly(main).setWidth(w);
				this.internalRender = true;



				if(Ext.isOpera && !this.secondPass){
					main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + 'px';
					this.secondPass = true;
					this.update.defer(10, this, [date]);
				}
			}
		}
	},


	beforeDestroy : function() {
		if(this.rendered){
			Ext.destroy(
				this.keyNav,
				this.monthPicker,
				this.eventEl,
				this.mbtn,
				this.nextRepeater,
				this.prevRepeater,
				this.cells.el,
				this.todayBtn
				);
			delete this.textNodes;
			delete this.cells.elements;
		}
	}


});

Ext.reg('datepicker', Ext.DatePicker);

Ext.LoadMask = function(el, config){
	this.el = Ext.get(el);
	Ext.apply(this, config);
	if(this.store){
		this.store.on({
			scope: this,
			beforeload: this.onBeforeLoad,
			load: this.onLoad,
			exception: this.onLoad
		});
		this.removeMask = Ext.value(this.removeMask, false);
	}else{
		var um = this.el.getUpdater();
		um.showLoadIndicator = false;
		um.on({
			scope: this,
			beforeupdate: this.onBeforeLoad,
			update: this.onLoad,
			failure: this.onLoad
		});
		this.removeMask = Ext.value(this.removeMask, true);
	}
};

Ext.LoadMask.prototype = {



	msg : 'Loading...',

	msgCls : 'x-mask-loading',


	disabled: false,


	disable : function(){
		this.disabled = true;
	},


	enable : function(){
		this.disabled = false;
	},


	onLoad : function(){
		this.el.unmask(this.removeMask);
	},


	onBeforeLoad : function(){
		if(!this.disabled){
			this.el.mask(this.msg, this.msgCls);
		}
	},


	show: function(){
		this.onBeforeLoad();
	},


	hide: function(){
		this.onLoad();
	},


	destroy : function(){
		if(this.store){
			this.store.un('beforeload', this.onBeforeLoad, this);
			this.store.un('load', this.onLoad, this);
			this.store.un('exception', this.onLoad, this);
		}else{
			var um = this.el.getUpdater();
			um.un('beforeupdate', this.onBeforeLoad, this);
			um.un('update', this.onLoad, this);
			um.un('failure', this.onLoad, this);
		}
	}
};

Ext.ns('Ext.slider');


Ext.slider.Thumb = Ext.extend(Object, {


	dragging: false,


	constructor: function(config) {

		Ext.apply(this, config || {}, {
			cls: 'x-slider-thumb',


			constrain: false
		});

		Ext.slider.Thumb.superclass.constructor.call(this, config);

		if (this.slider.vertical) {
			Ext.apply(this, Ext.slider.Thumb.Vertical);
		}
	},


	render: function() {
		this.el = this.slider.innerEl.insertFirst({
			cls: this.cls
			});

		this.initEvents();
	},


	enable: function() {
		this.disabled = false;
		this.el.removeClass(this.slider.disabledClass);
	},


	disable: function() {
		this.disabled = true;
		this.el.addClass(this.slider.disabledClass);
	},


	initEvents: function() {
		var el = this.el;

		el.addClassOnOver('x-slider-thumb-over');

		this.tracker = new Ext.dd.DragTracker({
			onBeforeStart: this.onBeforeDragStart.createDelegate(this),
			onStart      : this.onDragStart.createDelegate(this),
			onDrag       : this.onDrag.createDelegate(this),
			onEnd        : this.onDragEnd.createDelegate(this),
			tolerance    : 3,
			autoStart    : 300
		});

		this.tracker.initEl(el);
	},


	onBeforeDragStart : function(e) {
		if (this.disabled) {
			return false;
		} else {
			this.slider.promoteThumb(this);
			return true;
		}
	},


	onDragStart: function(e){
		this.el.addClass('x-slider-thumb-drag');
		this.dragging = true;
		this.dragStartValue = this.value;

		this.slider.fireEvent('dragstart', this.slider, e, this);
	},


	onDrag: function(e) {
		var slider   = this.slider,
		index    = this.index,
		newValue = this.getNewValue();

		if (this.constrain) {
			var above = slider.thumbs[index + 1],
			below = slider.thumbs[index - 1];

			if (below != undefined && newValue <= below.value) newValue = below.value;
			if (above != undefined && newValue >= above.value) newValue = above.value;
		}

		slider.setValue(index, newValue, false);
		slider.fireEvent('drag', slider, e, this);
	},

	getNewValue: function() {
		var slider   = this.slider,
		pos      = slider.innerEl.translatePoints(this.tracker.getXY());

		return Ext.util.Format.round(slider.reverseValue(pos.left), slider.decimalPrecision);
	},


	onDragEnd: function(e) {
		var slider = this.slider,
		value  = this.value;

		this.el.removeClass('x-slider-thumb-drag');

		this.dragging = false;
		slider.fireEvent('dragend', slider, e);

		if (this.dragStartValue != value) {
			slider.fireEvent('changecomplete', slider, value, this);
		}
	},


	destroy: function(){
		Ext.destroyMembers(this, 'tracker', 'el');
	}
});


Ext.slider.MultiSlider = Ext.extend(Ext.BoxComponent, {


	vertical: false,

	minValue: 0,

	maxValue: 100,

	decimalPrecision: 0,

	keyIncrement: 1,

	increment: 0,


	clickRange: [5,15],


	clickToChange : true,

	animate: true,

	constrainThumbs: true,


	topThumbZIndex: 10000,


	initComponent : function(){
		if(!Ext.isDefined(this.value)){
			this.value = this.minValue;
		}


		this.thumbs = [];

		Ext.slider.MultiSlider.superclass.initComponent.call(this);

		this.keyIncrement = Math.max(this.increment, this.keyIncrement);
		this.addEvents(

			'beforechange',


			'change',


			'changecomplete',


			'dragstart',


			'drag',


			'dragend'
			);


		if (this.values == undefined || Ext.isEmpty(this.values)) this.values = [0];

		var values = this.values;

		for (var i=0; i < values.length; i++) {
			this.addThumb(values[i]);
		}

		if(this.vertical){
			Ext.apply(this, Ext.slider.Vertical);
		}
	},


	addThumb: function(value) {
		var thumb = new Ext.slider.Thumb({
			value    : value,
			slider   : this,
			index    : this.thumbs.length,
			constrain: this.constrainThumbs
		});
		this.thumbs.push(thumb);


		if (this.rendered) thumb.render();
	},


	promoteThumb: function(topThumb) {
		var thumbs = this.thumbs,
		zIndex, thumb;

		for (var i = 0, j = thumbs.length; i < j; i++) {
			thumb = thumbs[i];

			if (thumb == topThumb) {
				zIndex = this.topThumbZIndex;
			} else {
				zIndex = '';
			}

			thumb.el.setStyle('zIndex', zIndex);
		}
	},


	onRender : function() {
		this.autoEl = {
			cls: 'x-slider ' + (this.vertical ? 'x-slider-vert' : 'x-slider-horz'),
			cn : {
				cls: 'x-slider-end',
				cn : {
					cls:'x-slider-inner',
					cn : [{
						tag:'a',
						cls:'x-slider-focus',
						href:"#",
						tabIndex: '-1',
						hidefocus:'on'
					}]
				}
			}
		};

		Ext.slider.MultiSlider.superclass.onRender.apply(this, arguments);

		this.endEl   = this.el.first();
		this.innerEl = this.endEl.first();
		this.focusEl = this.innerEl.child('.x-slider-focus');


		for (var i=0; i < this.thumbs.length; i++) {
			this.thumbs[i].render();
		}


		var thumb      = this.innerEl.child('.x-slider-thumb');
		this.halfThumb = (this.vertical ? thumb.getHeight() : thumb.getWidth()) / 2;

		this.initEvents();
	},


	initEvents : function(){
		this.mon(this.el, {
			scope    : this,
			mousedown: this.onMouseDown,
			keydown  : this.onKeyDown
		});

		this.focusEl.swallowEvent("click", true);
	},


	onMouseDown : function(e){
		if(this.disabled){
			return;
		}


		var thumbClicked = false;
		for (var i=0; i < this.thumbs.length; i++) {
			thumbClicked = thumbClicked || e.target == this.thumbs[i].el.dom;
		}

		if (this.clickToChange && !thumbClicked) {
			var local = this.innerEl.translatePoints(e.getXY());
			this.onClickChange(local);
		}
		this.focus();
	},


	onClickChange : function(local) {
		if (local.top > this.clickRange[0] && local.top < this.clickRange[1]) {

			var thumb = this.getNearest(local, 'left'),
			index = thumb.index;

			this.setValue(index, Ext.util.Format.round(this.reverseValue(local.left), this.decimalPrecision), undefined, true);
		}
	},


	getNearest: function(local, prop) {
		var localValue = prop == 'top' ? this.innerEl.getHeight() - local[prop] : local[prop],
		clickValue = this.reverseValue(localValue),
		nearestDistance = (this.maxValue - this.minValue) + 5,
		index = 0,
		nearest = null;

		for (var i=0; i < this.thumbs.length; i++) {
			var thumb = this.thumbs[i],
			value = thumb.value,
			dist  = Math.abs(value - clickValue);

			if (Math.abs(dist <= nearestDistance)) {
				nearest = thumb;
				index = i;
				nearestDistance = dist;
			}
		}
		return nearest;
	},


	onKeyDown : function(e){

		if(this.disabled || this.thumbs.length !== 1){
			e.preventDefault();
			return;
		}
		var k = e.getKey(),
		val;
		switch(k){
			case e.UP:
			case e.RIGHT:
				e.stopEvent();
				val = e.ctrlKey ? this.maxValue : this.getValue(0) + this.keyIncrement;
				this.setValue(0, val, undefined, true);
				break;
			case e.DOWN:
			case e.LEFT:
				e.stopEvent();
				val = e.ctrlKey ? this.minValue : this.getValue(0) - this.keyIncrement;
				this.setValue(0, val, undefined, true);
				break;
			default:
				e.preventDefault();
		}
	},


	doSnap : function(value){
		if (!(this.increment && value)) {
			return value;
		}
		var newValue = value,
		inc = this.increment,
		m = value % inc;
		if (m != 0) {
			newValue -= m;
			if (m * 2 >= inc) {
				newValue += inc;
			} else if (m * 2 < -inc) {
				newValue -= inc;
			}
		}
		return newValue.constrain(this.minValue,  this.maxValue);
	},


	afterRender : function(){
		Ext.slider.MultiSlider.superclass.afterRender.apply(this, arguments);

		for (var i=0; i < this.thumbs.length; i++) {
			var thumb = this.thumbs[i];

			if (thumb.value !== undefined) {
				var v = this.normalizeValue(thumb.value);

				if (v !== thumb.value) {

					this.setValue(i, v, false);
				} else {
					this.moveThumb(i, this.translateValue(v), false);
				}
			}
		};
	},


	getRatio : function(){
		var w = this.innerEl.getWidth(),
		v = this.maxValue - this.minValue;
		return v == 0 ? w : (w/v);
	},


	normalizeValue : function(v){
		v = this.doSnap(v);
		v = Ext.util.Format.round(v, this.decimalPrecision);
		v = v.constrain(this.minValue, this.maxValue);
		return v;
	},


	setMinValue : function(val){
		this.minValue = val;
		var i = 0,
		thumbs = this.thumbs,
		len = thumbs.length,
		t;

		for(; i < len; ++i){
			t = thumbs[i];
			t.value = t.value < val ? val : t.value;
		}
		this.syncThumb();
	},


	setMaxValue : function(val){
		this.maxValue = val;
		var i = 0,
		thumbs = this.thumbs,
		len = thumbs.length,
		t;

		for(; i < len; ++i){
			t = thumbs[i];
			t.value = t.value > val ? val : t.value;
		}
		this.syncThumb();
	},


	setValue : function(index, v, animate, changeComplete) {
		var thumb = this.thumbs[index],
		el    = thumb.el;

		v = this.normalizeValue(v);

		if (v !== thumb.value && this.fireEvent('beforechange', this, v, thumb.value, thumb) !== false) {
			thumb.value = v;
			if(this.rendered){
				this.moveThumb(index, this.translateValue(v), animate !== false);
				this.fireEvent('change', this, v, thumb);
				if(changeComplete){
					this.fireEvent('changecomplete', this, v, thumb);
				}
			}
		}
	},


	translateValue : function(v) {
		var ratio = this.getRatio();
		return (v * ratio) - (this.minValue * ratio) - this.halfThumb;
	},


	reverseValue : function(pos){
		var ratio = this.getRatio();
		return (pos + (this.minValue * ratio)) / ratio;
	},


	moveThumb: function(index, v, animate){
		var thumb = this.thumbs[index].el;

		if(!animate || this.animate === false){
			thumb.setLeft(v);
		}else{
			thumb.shift({
				left: v,
				stopFx: true,
				duration:.35
			});
		}
	},


	focus : function(){
		this.focusEl.focus(10);
	},


	onResize : function(w, h){
		var thumbs = this.thumbs,
		len = thumbs.length,
		i = 0;


		for(; i < len; ++i){
			thumbs[i].el.stopFx();
		}

		if(Ext.isNumber(w)){
			this.innerEl.setWidth(w - (this.el.getPadding('l') + this.endEl.getPadding('r')));
		}
		this.syncThumb();
		Ext.slider.MultiSlider.superclass.onResize.apply(this, arguments);
	},


	onDisable: function(){
		Ext.slider.MultiSlider.superclass.onDisable.call(this);

		for (var i=0; i < this.thumbs.length; i++) {
			var thumb = this.thumbs[i],
			el    = thumb.el;

			thumb.disable();

			if(Ext.isIE){


				var xy = el.getXY();
				el.hide();

				this.innerEl.addClass(this.disabledClass).dom.disabled = true;

				if (!this.thumbHolder) {
					this.thumbHolder = this.endEl.createChild({
						cls: 'x-slider-thumb ' + this.disabledClass
						});
				}

				this.thumbHolder.show().setXY(xy);
			}
		}
	},


	onEnable: function(){
		Ext.slider.MultiSlider.superclass.onEnable.call(this);

		for (var i=0; i < this.thumbs.length; i++) {
			var thumb = this.thumbs[i],
			el    = thumb.el;

			thumb.enable();

			if (Ext.isIE) {
				this.innerEl.removeClass(this.disabledClass).dom.disabled = false;

				if (this.thumbHolder) this.thumbHolder.hide();

				el.show();
				this.syncThumb();
			}
		}
	},


	syncThumb : function() {
		if (this.rendered) {
			for (var i=0; i < this.thumbs.length; i++) {
				this.moveThumb(i, this.translateValue(this.thumbs[i].value));
			}
		}
	},


	getValue : function(index) {
		return this.thumbs[index].value;
	},


	getValues: function() {
		var values = [];

		for (var i=0; i < this.thumbs.length; i++) {
			values.push(this.thumbs[i].value);
		}

		return values;
	},


	beforeDestroy : function(){
		var thumbs = this.thumbs;
		for(var i = 0, len = thumbs.length; i < len; ++i){
			thumbs[i].destroy();
			thumbs[i] = null;
		}
		Ext.destroyMembers(this, 'endEl', 'innerEl', 'focusEl', 'thumbHolder');
		Ext.slider.MultiSlider.superclass.beforeDestroy.call(this);
	}
});

Ext.reg('multislider', Ext.slider.MultiSlider);


Ext.slider.SingleSlider = Ext.extend(Ext.slider.MultiSlider, {
	constructor: function(config) {
		config = config || {};

		Ext.applyIf(config, {
			values: [config.value || 0]
		});

		Ext.slider.SingleSlider.superclass.constructor.call(this, config);
	},


	getValue: function() {

		return Ext.slider.SingleSlider.superclass.getValue.call(this, 0);
	},


	setValue: function(value, animate) {
		var args = Ext.toArray(arguments),
		len  = args.length;




		if (len == 1 || (len <= 3 && typeof arguments[1] != 'number')) {
			args.unshift(0);
		}

		return Ext.slider.SingleSlider.superclass.setValue.apply(this, args);
	},


	syncThumb : function() {
		return Ext.slider.SingleSlider.superclass.syncThumb.apply(this, [0].concat(arguments));
	},


	getNearest : function(){

		return this.thumbs[0];
	}
});


Ext.Slider = Ext.slider.SingleSlider;

Ext.reg('slider', Ext.slider.SingleSlider);


Ext.slider.Vertical = {
	onResize : function(w, h){
		this.innerEl.setHeight(h - (this.el.getPadding('t') + this.endEl.getPadding('b')));
		this.syncThumb();
	},

	getRatio : function(){
		var h = this.innerEl.getHeight(),
		v = this.maxValue - this.minValue;
		return h/v;
	},

	moveThumb: function(index, v, animate) {
		var thumb = this.thumbs[index],
		el    = thumb.el;

		if (!animate || this.animate === false) {
			el.setBottom(v);
		} else {
			el.shift({
				bottom: v,
				stopFx: true,
				duration:.35
			});
		}
	},

	onClickChange : function(local) {
		if (local.left > this.clickRange[0] && local.left < this.clickRange[1]) {
			var thumb = this.getNearest(local, 'top'),
			index = thumb.index,
			value = this.minValue + this.reverseValue(this.innerEl.getHeight() - local.top);

			this.setValue(index, Ext.util.Format.round(value, this.decimalPrecision), undefined, true);
		}
	}
};


Ext.slider.Thumb.Vertical = {
	getNewValue: function() {
		var slider   = this.slider,
		innerEl  = slider.innerEl,
		pos      = innerEl.translatePoints(this.tracker.getXY()),
		bottom   = innerEl.getHeight() - pos.top;

		return slider.minValue + Ext.util.Format.round(bottom / slider.getRatio(), slider.decimalPrecision);
	}
};

Ext.ProgressBar = Ext.extend(Ext.BoxComponent, {

	baseCls : 'x-progress',


	animate : false,


	waitTimer : null,


	initComponent : function(){
		Ext.ProgressBar.superclass.initComponent.call(this);
		this.addEvents(

			"update"
			);
	},


	onRender : function(ct, position){
		var tpl = new Ext.Template(
			'<div class="{cls}-wrap">',
			'<div class="{cls}-inner">',
			'<div class="{cls}-bar">',
			'<div class="{cls}-text">',
			'<div>&#160;</div>',
			'</div>',
			'</div>',
			'<div class="{cls}-text {cls}-text-back">',
			'<div>&#160;</div>',
			'</div>',
			'</div>',
			'</div>'
			);

		this.el = position ? tpl.insertBefore(position, {
			cls: this.baseCls
			}, true)
		: tpl.append(ct, {
			cls: this.baseCls
			}, true);

		if(this.id){
			this.el.dom.id = this.id;
		}
		var inner = this.el.dom.firstChild;
		this.progressBar = Ext.get(inner.firstChild);

		if(this.textEl){

			this.textEl = Ext.get(this.textEl);
			delete this.textTopEl;
		}else{

			this.textTopEl = Ext.get(this.progressBar.dom.firstChild);
			var textBackEl = Ext.get(inner.childNodes[1]);
			this.textTopEl.setStyle("z-index", 99).addClass('x-hidden');
			this.textEl = new Ext.CompositeElement([this.textTopEl.dom.firstChild, textBackEl.dom.firstChild]);
			this.textEl.setWidth(inner.offsetWidth);
		}
		this.progressBar.setHeight(inner.offsetHeight);
	},


	afterRender : function(){
		Ext.ProgressBar.superclass.afterRender.call(this);
		if(this.value){
			this.updateProgress(this.value, this.text);
		}else{
			this.updateText(this.text);
		}
	},


	updateProgress : function(value, text, animate){
		this.value = value || 0;
		if(text){
			this.updateText(text);
		}
		if(this.rendered && !this.isDestroyed){
			var w = Math.floor(value*this.el.dom.firstChild.offsetWidth);
			this.progressBar.setWidth(w, animate === true || (animate !== false && this.animate));
			if(this.textTopEl){

				this.textTopEl.removeClass('x-hidden').setWidth(w);
			}
		}
		this.fireEvent('update', this, value, text);
		return this;
	},


	wait : function(o){
		if(!this.waitTimer){
			var scope = this;
			o = o || {};
			this.updateText(o.text);
			this.waitTimer = Ext.TaskMgr.start({
				run: function(i){
					var inc = o.increment || 10;
					i -= 1;
					this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*0.01, null, o.animate);
				},
				interval: o.interval || 1000,
				duration: o.duration,
				onStop: function(){
					if(o.fn){
						o.fn.apply(o.scope || this);
					}
					this.reset();
				},
				scope: scope
			});
		}
		return this;
	},


	isWaiting : function(){
		return this.waitTimer !== null;
	},


	updateText : function(text){
		this.text = text || '&#160;';
		if(this.rendered){
			this.textEl.update(this.text);
		}
		return this;
	},


	syncProgressBar : function(){
		if(this.value){
			this.updateProgress(this.value, this.text);
		}
		return this;
	},


	setSize : function(w, h){
		Ext.ProgressBar.superclass.setSize.call(this, w, h);
		if(this.textTopEl){
			var inner = this.el.dom.firstChild;
			this.textEl.setSize(inner.offsetWidth, inner.offsetHeight);
		}
		this.syncProgressBar();
		return this;
	},


	reset : function(hide){
		this.updateProgress(0);
		if(this.textTopEl){
			this.textTopEl.addClass('x-hidden');
		}
		this.clearTimer();
		if(hide === true){
			this.hide();
		}
		return this;
	},


	clearTimer : function(){
		if(this.waitTimer){
			this.waitTimer.onStop = null;
			Ext.TaskMgr.stop(this.waitTimer);
			this.waitTimer = null;
		}
	},

	onDestroy: function(){
		this.clearTimer();
		if(this.rendered){
			if(this.textEl.isComposite){
				this.textEl.clear();
			}
			Ext.destroyMembers(this, 'textEl', 'progressBar', 'textTopEl');
		}
		Ext.ProgressBar.superclass.onDestroy.call(this);
	}
});
Ext.reg('progress', Ext.ProgressBar);

(function() {

	var Event=Ext.EventManager;
	var Dom=Ext.lib.Dom;


	Ext.dd.DragDrop = function(id, sGroup, config) {
		if(id) {
			this.init(id, sGroup, config);
		}
	};

	Ext.dd.DragDrop.prototype = {




		id: null,


		config: null,


		dragElId: null,


		handleElId: null,


		invalidHandleTypes: null,


		invalidHandleIds: null,


		invalidHandleClasses: null,


		startPageX: 0,


		startPageY: 0,


		groups: null,


		locked: false,


		lock: function() {
			this.locked = true;
		},


		moveOnly: false,


		unlock: function() {
			this.locked = false;
		},


		isTarget: true,


		padding: null,


		_domRef: null,


		__ygDragDrop: true,


		constrainX: false,


		constrainY: false,


		minX: 0,


		maxX: 0,


		minY: 0,


		maxY: 0,


		maintainOffset: false,


		xTicks: null,


		yTicks: null,


		primaryButtonOnly: true,


		available: false,


		hasOuterHandles: false,


		b4StartDrag: function(x, y) { },


		startDrag: function(x, y) {  },


		b4Drag: function(e) { },


		onDrag: function(e) {  },


		onDragEnter: function(e, id) {  },


		b4DragOver: function(e) { },


		onDragOver: function(e, id) {  },


		b4DragOut: function(e) { },


		onDragOut: function(e, id) {  },


		b4DragDrop: function(e) { },


		onDragDrop: function(e, id) {  },


		onInvalidDrop: function(e) {  },


		b4EndDrag: function(e) { },


		endDrag: function(e) {  },


		b4MouseDown: function(e) {  },


		onMouseDown: function(e) {  },


		onMouseUp: function(e) {  },


		onAvailable: function () {
		},


		defaultPadding : {
			left:0,
			right:0,
			top:0,
			bottom:0
		},


		constrainTo : function(constrainTo, pad, inContent){
			if(Ext.isNumber(pad)){
				pad = {
					left: pad,
					right:pad,
					top:pad,
					bottom:pad
				};
			}
			pad = pad || this.defaultPadding;
			var b = Ext.get(this.getEl()).getBox(),
			ce = Ext.get(constrainTo),
			s = ce.getScroll(),
			c,
			cd = ce.dom;
			if(cd == document.body){
				c = {
					x: s.left,
					y: s.top,
					width: Ext.lib.Dom.getViewWidth(),
					height: Ext.lib.Dom.getViewHeight()
					};
			}else{
				var xy = ce.getXY();
				c = {
					x : xy[0],
					y: xy[1],
					width: cd.clientWidth,
					height: cd.clientHeight
					};
			}


			var topSpace = b.y - c.y,
			leftSpace = b.x - c.x;

			this.resetConstraints();
			this.setXConstraint(leftSpace - (pad.left||0),
				c.width - leftSpace - b.width - (pad.right||0),
				this.xTickSize
				);
			this.setYConstraint(topSpace - (pad.top||0),
				c.height - topSpace - b.height - (pad.bottom||0),
				this.yTickSize
				);
		},


		getEl: function() {
			if (!this._domRef) {
				this._domRef = Ext.getDom(this.id);
			}

			return this._domRef;
		},


		getDragEl: function() {
			return Ext.getDom(this.dragElId);
		},


		init: function(id, sGroup, config) {
			this.initTarget(id, sGroup, config);
			Event.on(this.id, "mousedown", this.handleMouseDown, this);

		},


		initTarget: function(id, sGroup, config) {


			this.config = config || {};


			this.DDM = Ext.dd.DDM;

			this.groups = {};



			if (typeof id !== "string") {
				id = Ext.id(id);
			}


			this.id = id;


			this.addToGroup((sGroup) ? sGroup : "default");



			this.handleElId = id;


			this.setDragElId(id);


			this.invalidHandleTypes = {
				A: "A"
			};
			this.invalidHandleIds = {};
			this.invalidHandleClasses = [];

			this.applyConfig();

			this.handleOnAvailable();
		},


		applyConfig: function() {



			this.padding           = this.config.padding || [0, 0, 0, 0];
			this.isTarget          = (this.config.isTarget !== false);
			this.maintainOffset    = (this.config.maintainOffset);
			this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);

		},


		handleOnAvailable: function() {
			this.available = true;
			this.resetConstraints();
			this.onAvailable();
		},


		setPadding: function(iTop, iRight, iBot, iLeft) {

			if (!iRight && 0 !== iRight) {
				this.padding = [iTop, iTop, iTop, iTop];
			} else if (!iBot && 0 !== iBot) {
				this.padding = [iTop, iRight, iTop, iRight];
			} else {
				this.padding = [iTop, iRight, iBot, iLeft];
			}
		},


		setInitPosition: function(diffX, diffY) {
			var el = this.getEl();

			if (!this.DDM.verifyEl(el)) {
				return;
			}

			var dx = diffX || 0;
			var dy = diffY || 0;

			var p = Dom.getXY( el );

			this.initPageX = p[0] - dx;
			this.initPageY = p[1] - dy;

			this.lastPageX = p[0];
			this.lastPageY = p[1];

			this.setStartPosition(p);
		},


		setStartPosition: function(pos) {
			var p = pos || Dom.getXY( this.getEl() );
			this.deltaSetXY = null;

			this.startPageX = p[0];
			this.startPageY = p[1];
		},


		addToGroup: function(sGroup) {
			this.groups[sGroup] = true;
			this.DDM.regDragDrop(this, sGroup);
		},


		removeFromGroup: function(sGroup) {
			if (this.groups[sGroup]) {
				delete this.groups[sGroup];
			}

			this.DDM.removeDDFromGroup(this, sGroup);
		},


		setDragElId: function(id) {
			this.dragElId = id;
		},


		setHandleElId: function(id) {
			if (typeof id !== "string") {
				id = Ext.id(id);
			}
			this.handleElId = id;
			this.DDM.regHandle(this.id, id);
		},


		setOuterHandleElId: function(id) {
			if (typeof id !== "string") {
				id = Ext.id(id);
			}
			Event.on(id, "mousedown",
				this.handleMouseDown, this);
			this.setHandleElId(id);

			this.hasOuterHandles = true;
		},


		unreg: function() {
			Event.un(this.id, "mousedown",
				this.handleMouseDown);
			this._domRef = null;
			this.DDM._remove(this);
		},

		destroy : function(){
			this.unreg();
		},


		isLocked: function() {
			return (this.DDM.isLocked() || this.locked);
		},


		handleMouseDown: function(e, oDD){
			if (this.primaryButtonOnly && e.button != 0) {
				return;
			}

			if (this.isLocked()) {
				return;
			}

			this.DDM.refreshCache(this.groups);

			var pt = new Ext.lib.Point(Ext.lib.Event.getPageX(e), Ext.lib.Event.getPageY(e));
			if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) )  {
			} else {
				if (this.clickValidator(e)) {


					this.setStartPosition();

					this.b4MouseDown(e);
					this.onMouseDown(e);

					this.DDM.handleMouseDown(e, this);

					this.DDM.stopEvent(e);
				} else {


			}
			}
		},

		clickValidator: function(e) {
			var target = e.getTarget();
			return ( this.isValidHandleChild(target) &&
				(this.id == this.handleElId ||
					this.DDM.handleWasClicked(target, this.id)) );
		},


		addInvalidHandleType: function(tagName) {
			var type = tagName.toUpperCase();
			this.invalidHandleTypes[type] = type;
		},


		addInvalidHandleId: function(id) {
			if (typeof id !== "string") {
				id = Ext.id(id);
			}
			this.invalidHandleIds[id] = id;
		},


		addInvalidHandleClass: function(cssClass) {
			this.invalidHandleClasses.push(cssClass);
		},


		removeInvalidHandleType: function(tagName) {
			var type = tagName.toUpperCase();

			delete this.invalidHandleTypes[type];
		},


		removeInvalidHandleId: function(id) {
			if (typeof id !== "string") {
				id = Ext.id(id);
			}
			delete this.invalidHandleIds[id];
		},


		removeInvalidHandleClass: function(cssClass) {
			for (var i=0, len=this.invalidHandleClasses.length; i<len; ++i) {
				if (this.invalidHandleClasses[i] == cssClass) {
					delete this.invalidHandleClasses[i];
				}
			}
		},


		isValidHandleChild: function(node) {

			var valid = true;

			var nodeName;
			try {
				nodeName = node.nodeName.toUpperCase();
			} catch(e) {
				nodeName = node.nodeName;
			}
			valid = valid && !this.invalidHandleTypes[nodeName];
			valid = valid && !this.invalidHandleIds[node.id];

			for (var i=0, len=this.invalidHandleClasses.length; valid && i<len; ++i) {
				valid = !Ext.fly(node).hasClass(this.invalidHandleClasses[i]);
			}


			return valid;

		},


		setXTicks: function(iStartX, iTickSize) {
			this.xTicks = [];
			this.xTickSize = iTickSize;

			var tickMap = {};

			for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {
				if (!tickMap[i]) {
					this.xTicks[this.xTicks.length] = i;
					tickMap[i] = true;
				}
			}

			for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {
				if (!tickMap[i]) {
					this.xTicks[this.xTicks.length] = i;
					tickMap[i] = true;
				}
			}

			this.xTicks.sort(this.DDM.numericSort) ;
		},


		setYTicks: function(iStartY, iTickSize) {
			this.yTicks = [];
			this.yTickSize = iTickSize;

			var tickMap = {};

			for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {
				if (!tickMap[i]) {
					this.yTicks[this.yTicks.length] = i;
					tickMap[i] = true;
				}
			}

			for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {
				if (!tickMap[i]) {
					this.yTicks[this.yTicks.length] = i;
					tickMap[i] = true;
				}
			}

			this.yTicks.sort(this.DDM.numericSort) ;
		},


		setXConstraint: function(iLeft, iRight, iTickSize) {
			this.leftConstraint = iLeft;
			this.rightConstraint = iRight;

			this.minX = this.initPageX - iLeft;
			this.maxX = this.initPageX + iRight;
			if (iTickSize) {
				this.setXTicks(this.initPageX, iTickSize);
			}

			this.constrainX = true;
		},


		clearConstraints: function() {
			this.constrainX = false;
			this.constrainY = false;
			this.clearTicks();
		},


		clearTicks: function() {
			this.xTicks = null;
			this.yTicks = null;
			this.xTickSize = 0;
			this.yTickSize = 0;
		},


		setYConstraint: function(iUp, iDown, iTickSize) {
			this.topConstraint = iUp;
			this.bottomConstraint = iDown;

			this.minY = this.initPageY - iUp;
			this.maxY = this.initPageY + iDown;
			if (iTickSize) {
				this.setYTicks(this.initPageY, iTickSize);
			}

			this.constrainY = true;

		},


		resetConstraints: function() {

			if (this.initPageX || this.initPageX === 0) {

				var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;
				var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;

				this.setInitPosition(dx, dy);


			} else {
				this.setInitPosition();
			}

			if (this.constrainX) {
				this.setXConstraint( this.leftConstraint,
					this.rightConstraint,
					this.xTickSize        );
			}

			if (this.constrainY) {
				this.setYConstraint( this.topConstraint,
					this.bottomConstraint,
					this.yTickSize         );
			}
		},


		getTick: function(val, tickArray) {
			if (!tickArray) {


				return val;
			} else if (tickArray[0] >= val) {


				return tickArray[0];
			} else {
				for (var i=0, len=tickArray.length; i<len; ++i) {
					var next = i + 1;
					if (tickArray[next] && tickArray[next] >= val) {
						var diff1 = val - tickArray[i];
						var diff2 = tickArray[next] - val;
						return (diff2 > diff1) ? tickArray[i] : tickArray[next];
					}
				}



				return tickArray[tickArray.length - 1];
			}
		},


		toString: function() {
			return ("DragDrop " + this.id);
		}

	};

})();




if (!Ext.dd.DragDropMgr) {


	Ext.dd.DragDropMgr = function() {

		var Event = Ext.EventManager;

		return {


			ids: {},


			handleIds: {},


			dragCurrent: null,


			dragOvers: {},


			deltaX: 0,


			deltaY: 0,


			preventDefault: true,


			stopPropagation: true,


			initialized: false,


			locked: false,


			init: function() {
				this.initialized = true;
			},


			POINT: 0,


			INTERSECT: 1,


			mode: 0,


			_execOnAll: function(sMethod, args) {
				for (var i in this.ids) {
					for (var j in this.ids[i]) {
						var oDD = this.ids[i][j];
						if (! this.isTypeOfDD(oDD)) {
							continue;
						}
						oDD[sMethod].apply(oDD, args);
					}
				}
			},


			_onLoad: function() {

				this.init();


				Event.on(document, "mouseup",   this.handleMouseUp, this, true);
				Event.on(document, "mousemove", this.handleMouseMove, this, true);
				Event.on(window,   "unload",    this._onUnload, this, true);
				Event.on(window,   "resize",    this._onResize, this, true);


			},


			_onResize: function(e) {
				this._execOnAll("resetConstraints", []);
			},


			lock: function() {
				this.locked = true;
			},


			unlock: function() {
				this.locked = false;
			},


			isLocked: function() {
				return this.locked;
			},


			locationCache: {},


			useCache: true,


			clickPixelThresh: 3,


			clickTimeThresh: 350,


			dragThreshMet: false,


			clickTimeout: null,


			startX: 0,


			startY: 0,


			regDragDrop: function(oDD, sGroup) {
				if (!this.initialized) {
					this.init();
				}

				if (!this.ids[sGroup]) {
					this.ids[sGroup] = {};
				}
				this.ids[sGroup][oDD.id] = oDD;
			},


			removeDDFromGroup: function(oDD, sGroup) {
				if (!this.ids[sGroup]) {
					this.ids[sGroup] = {};
				}

				var obj = this.ids[sGroup];
				if (obj && obj[oDD.id]) {
					delete obj[oDD.id];
				}
			},


			_remove: function(oDD) {
				for (var g in oDD.groups) {
					if (g && this.ids[g] && this.ids[g][oDD.id]) {
						delete this.ids[g][oDD.id];
					}
				}
				delete this.handleIds[oDD.id];
			},


			regHandle: function(sDDId, sHandleId) {
				if (!this.handleIds[sDDId]) {
					this.handleIds[sDDId] = {};
				}
				this.handleIds[sDDId][sHandleId] = sHandleId;
			},


			isDragDrop: function(id) {
				return ( this.getDDById(id) ) ? true : false;
			},


			getRelated: function(p_oDD, bTargetsOnly) {
				var oDDs = [];
				for (var i in p_oDD.groups) {
					for (var j in this.ids[i]) {
						var dd = this.ids[i][j];
						if (! this.isTypeOfDD(dd)) {
							continue;
						}
						if (!bTargetsOnly || dd.isTarget) {
							oDDs[oDDs.length] = dd;
						}
					}
				}

				return oDDs;
			},


			isLegalTarget: function (oDD, oTargetDD) {
				var targets = this.getRelated(oDD, true);
				for (var i=0, len=targets.length;i<len;++i) {
					if (targets[i].id == oTargetDD.id) {
						return true;
					}
				}

				return false;
			},


			isTypeOfDD: function (oDD) {
				return (oDD && oDD.__ygDragDrop);
			},


			isHandle: function(sDDId, sHandleId) {
				return ( this.handleIds[sDDId] &&
					this.handleIds[sDDId][sHandleId] );
			},


			getDDById: function(id) {
				for (var i in this.ids) {
					if (this.ids[i][id]) {
						return this.ids[i][id];
					}
				}
				return null;
			},


			handleMouseDown: function(e, oDD) {
				if(Ext.QuickTips){
					Ext.QuickTips.ddDisable();
				}
				if(this.dragCurrent){


					this.handleMouseUp(e);
				}

				this.currentTarget = e.getTarget();
				this.dragCurrent = oDD;

				var el = oDD.getEl();


				this.startX = e.getPageX();
				this.startY = e.getPageY();

				this.deltaX = this.startX - el.offsetLeft;
				this.deltaY = this.startY - el.offsetTop;

				this.dragThreshMet = false;

				this.clickTimeout = setTimeout(
					function() {
						var DDM = Ext.dd.DDM;
						DDM.startDrag(DDM.startX, DDM.startY);
					},
					this.clickTimeThresh );
			},


			startDrag: function(x, y) {
				clearTimeout(this.clickTimeout);
				if (this.dragCurrent) {
					this.dragCurrent.b4StartDrag(x, y);
					this.dragCurrent.startDrag(x, y);
				}
				this.dragThreshMet = true;
			},


			handleMouseUp: function(e) {

				if(Ext.QuickTips){
					Ext.QuickTips.ddEnable();
				}
				if (! this.dragCurrent) {
					return;
				}

				clearTimeout(this.clickTimeout);

				if (this.dragThreshMet) {
					this.fireEvents(e, true);
				} else {
				}

				this.stopDrag(e);

				this.stopEvent(e);
			},


			stopEvent: function(e){
				if(this.stopPropagation) {
					e.stopPropagation();
				}

				if (this.preventDefault) {
					e.preventDefault();
				}
			},


			stopDrag: function(e) {

				if (this.dragCurrent) {
					if (this.dragThreshMet) {
						this.dragCurrent.b4EndDrag(e);
						this.dragCurrent.endDrag(e);
					}

					this.dragCurrent.onMouseUp(e);
				}

				this.dragCurrent = null;
				this.dragOvers = {};
			},


			handleMouseMove: function(e) {
				if (! this.dragCurrent) {
					return true;
				}



				if (Ext.isIE && (e.button !== 0 && e.button !== 1 && e.button !== 2)) {
					this.stopEvent(e);
					return this.handleMouseUp(e);
				}

				if (!this.dragThreshMet) {
					var diffX = Math.abs(this.startX - e.getPageX());
					var diffY = Math.abs(this.startY - e.getPageY());
					if (diffX > this.clickPixelThresh ||
						diffY > this.clickPixelThresh) {
						this.startDrag(this.startX, this.startY);
					}
				}

				if (this.dragThreshMet) {
					this.dragCurrent.b4Drag(e);
					this.dragCurrent.onDrag(e);
					if(!this.dragCurrent.moveOnly){
						this.fireEvents(e, false);
					}
				}

				this.stopEvent(e);

				return true;
			},


			fireEvents: function(e, isDrop) {
				var dc = this.dragCurrent;



				if (!dc || dc.isLocked()) {
					return;
				}

				var pt = e.getPoint();


				var oldOvers = [];

				var outEvts   = [];
				var overEvts  = [];
				var dropEvts  = [];
				var enterEvts = [];



				for (var i in this.dragOvers) {

					var ddo = this.dragOvers[i];

					if (! this.isTypeOfDD(ddo)) {
						continue;
					}

					if (! this.isOverTarget(pt, ddo, this.mode)) {
						outEvts.push( ddo );
					}

					oldOvers[i] = true;
					delete this.dragOvers[i];
				}

				for (var sGroup in dc.groups) {

					if ("string" != typeof sGroup) {
						continue;
					}

					for (i in this.ids[sGroup]) {
						var oDD = this.ids[sGroup][i];
						if (! this.isTypeOfDD(oDD)) {
							continue;
						}

						if (oDD.isTarget && !oDD.isLocked() && ((oDD != dc) || (dc.ignoreSelf === false))) {
							if (this.isOverTarget(pt, oDD, this.mode)) {

								if (isDrop) {
									dropEvts.push( oDD );

								} else {


									if (!oldOvers[oDD.id]) {
										enterEvts.push( oDD );

									} else {
										overEvts.push( oDD );
									}

									this.dragOvers[oDD.id] = oDD;
								}
							}
						}
					}
				}

				if (this.mode) {
					if (outEvts.length) {
						dc.b4DragOut(e, outEvts);
						dc.onDragOut(e, outEvts);
					}

					if (enterEvts.length) {
						dc.onDragEnter(e, enterEvts);
					}

					if (overEvts.length) {
						dc.b4DragOver(e, overEvts);
						dc.onDragOver(e, overEvts);
					}

					if (dropEvts.length) {
						dc.b4DragDrop(e, dropEvts);
						dc.onDragDrop(e, dropEvts);
					}

				} else {

					var len = 0;
					for (i=0, len=outEvts.length; i<len; ++i) {
						dc.b4DragOut(e, outEvts[i].id);
						dc.onDragOut(e, outEvts[i].id);
					}


					for (i=0,len=enterEvts.length; i<len; ++i) {

						dc.onDragEnter(e, enterEvts[i].id);
					}


					for (i=0,len=overEvts.length; i<len; ++i) {
						dc.b4DragOver(e, overEvts[i].id);
						dc.onDragOver(e, overEvts[i].id);
					}


					for (i=0, len=dropEvts.length; i<len; ++i) {
						dc.b4DragDrop(e, dropEvts[i].id);
						dc.onDragDrop(e, dropEvts[i].id);
					}

				}


				if (isDrop && !dropEvts.length) {
					dc.onInvalidDrop(e);
				}

			},


			getBestMatch: function(dds) {
				var winner = null;






				var len = dds.length;

				if (len == 1) {
					winner = dds[0];
				} else {

					for (var i=0; i<len; ++i) {
						var dd = dds[i];



						if (dd.cursorIsOver) {
							winner = dd;
							break;

						} else {
							if (!winner ||
								winner.overlap.getArea() < dd.overlap.getArea()) {
								winner = dd;
							}
						}
					}
				}

				return winner;
			},


			refreshCache: function(groups) {
				for (var sGroup in groups) {
					if ("string" != typeof sGroup) {
						continue;
					}
					for (var i in this.ids[sGroup]) {
						var oDD = this.ids[sGroup][i];

						if (this.isTypeOfDD(oDD)) {

							var loc = this.getLocation(oDD);
							if (loc) {
								this.locationCache[oDD.id] = loc;
							} else {
								delete this.locationCache[oDD.id];



							}
						}
					}
				}
			},


			verifyEl: function(el) {
				if (el) {
					var parent;
					if(Ext.isIE){
						try{
							parent = el.offsetParent;
						}catch(e){}
					}else{
						parent = el.offsetParent;
					}
					if (parent) {
						return true;
					}
				}

				return false;
			},


			getLocation: function(oDD) {
				if (! this.isTypeOfDD(oDD)) {
					return null;
				}

				var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l;

				try {
					pos= Ext.lib.Dom.getXY(el);
				} catch (e) { }

				if (!pos) {
					return null;
				}

				x1 = pos[0];
				x2 = x1 + el.offsetWidth;
				y1 = pos[1];
				y2 = y1 + el.offsetHeight;

				t = y1 - oDD.padding[0];
				r = x2 + oDD.padding[1];
				b = y2 + oDD.padding[2];
				l = x1 - oDD.padding[3];

				return new Ext.lib.Region( t, r, b, l );
			},


			isOverTarget: function(pt, oTarget, intersect) {

				var loc = this.locationCache[oTarget.id];
				if (!loc || !this.useCache) {
					loc = this.getLocation(oTarget);
					this.locationCache[oTarget.id] = loc;

				}

				if (!loc) {
					return false;
				}

				oTarget.cursorIsOver = loc.contains( pt );






				var dc = this.dragCurrent;
				if (!dc || !dc.getTargetCoord ||
					(!intersect && !dc.constrainX && !dc.constrainY)) {
					return oTarget.cursorIsOver;
				}

				oTarget.overlap = null;





				var pos = dc.getTargetCoord(pt.x, pt.y);

				var el = dc.getDragEl();
				var curRegion = new Ext.lib.Region( pos.y,
					pos.x + el.offsetWidth,
					pos.y + el.offsetHeight,
					pos.x );

				var overlap = curRegion.intersect(loc);

				if (overlap) {
					oTarget.overlap = overlap;
					return (intersect) ? true : oTarget.cursorIsOver;
				} else {
					return false;
				}
			},


			_onUnload: function(e, me) {
				Ext.dd.DragDropMgr.unregAll();
			},


			unregAll: function() {

				if (this.dragCurrent) {
					this.stopDrag();
					this.dragCurrent = null;
				}

				this._execOnAll("unreg", []);

				for (var i in this.elementCache) {
					delete this.elementCache[i];
				}

				this.elementCache = {};
				this.ids = {};
			},


			elementCache: {},


			getElWrapper: function(id) {
				var oWrapper = this.elementCache[id];
				if (!oWrapper || !oWrapper.el) {
					oWrapper = this.elementCache[id] =
					new this.ElementWrapper(Ext.getDom(id));
				}
				return oWrapper;
			},


			getElement: function(id) {
				return Ext.getDom(id);
			},


			getCss: function(id) {
				var el = Ext.getDom(id);
				return (el) ? el.style : null;
			},


			ElementWrapper: function(el) {

				this.el = el || null;

				this.id = this.el && el.id;

				this.css = this.el && el.style;
			},


			getPosX: function(el) {
				return Ext.lib.Dom.getX(el);
			},


			getPosY: function(el) {
				return Ext.lib.Dom.getY(el);
			},


			swapNode: function(n1, n2) {
				if (n1.swapNode) {
					n1.swapNode(n2);
				} else {
					var p = n2.parentNode;
					var s = n2.nextSibling;

					if (s == n1) {
						p.insertBefore(n1, n2);
					} else if (n2 == n1.nextSibling) {
						p.insertBefore(n2, n1);
					} else {
						n1.parentNode.replaceChild(n2, n1);
						p.insertBefore(n1, s);
					}
				}
			},


			getScroll: function () {
				var t, l, dde=document.documentElement, db=document.body;
				if (dde && (dde.scrollTop || dde.scrollLeft)) {
					t = dde.scrollTop;
					l = dde.scrollLeft;
				} else if (db) {
					t = db.scrollTop;
					l = db.scrollLeft;
				} else {

				}
				return {
					top: t,
					left: l
				};
			},


			getStyle: function(el, styleProp) {
				return Ext.fly(el).getStyle(styleProp);
			},


			getScrollTop: function () {
				return this.getScroll().top;
			},


			getScrollLeft: function () {
				return this.getScroll().left;
			},


			moveToEl: function (moveEl, targetEl) {
				var aCoord = Ext.lib.Dom.getXY(targetEl);
				Ext.lib.Dom.setXY(moveEl, aCoord);
			},


			numericSort: function(a, b) {
				return (a - b);
			},


			_timeoutCount: 0,


			_addListeners: function() {
				var DDM = Ext.dd.DDM;
				if ( Ext.lib.Event && document ) {
					DDM._onLoad();
				} else {
					if (DDM._timeoutCount > 2000) {
					} else {
						setTimeout(DDM._addListeners, 10);
						if (document && document.body) {
							DDM._timeoutCount += 1;
						}
					}
				}
			},


			handleWasClicked: function(node, id) {
				if (this.isHandle(id, node.id)) {
					return true;
				} else {

					var p = node.parentNode;

					while (p) {
						if (this.isHandle(id, p.id)) {
							return true;
						} else {
							p = p.parentNode;
						}
					}
				}

				return false;
			}

		};

	}();


	Ext.dd.DDM = Ext.dd.DragDropMgr;
	Ext.dd.DDM._addListeners();

}


Ext.dd.DD = function(id, sGroup, config) {
	if (id) {
		this.init(id, sGroup, config);
	}
};

Ext.extend(Ext.dd.DD, Ext.dd.DragDrop, {


	scroll: true,


	autoOffset: function(iPageX, iPageY) {
		var x = iPageX - this.startPageX;
		var y = iPageY - this.startPageY;
		this.setDelta(x, y);
	},


	setDelta: function(iDeltaX, iDeltaY) {
		this.deltaX = iDeltaX;
		this.deltaY = iDeltaY;
	},


	setDragElPos: function(iPageX, iPageY) {



		var el = this.getDragEl();
		this.alignElWithMouse(el, iPageX, iPageY);
	},


	alignElWithMouse: function(el, iPageX, iPageY) {
		var oCoord = this.getTargetCoord(iPageX, iPageY);
		var fly = el.dom ? el : Ext.fly(el, '_dd');
		if (!this.deltaSetXY) {
			var aCoord = [oCoord.x, oCoord.y];
			fly.setXY(aCoord);
			var newLeft = fly.getLeft(true);
			var newTop  = fly.getTop(true);
			this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];
		} else {
			fly.setLeftTop(oCoord.x + this.deltaSetXY[0], oCoord.y + this.deltaSetXY[1]);
		}

		this.cachePosition(oCoord.x, oCoord.y);
		this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
		return oCoord;
	},


	cachePosition: function(iPageX, iPageY) {
		if (iPageX) {
			this.lastPageX = iPageX;
			this.lastPageY = iPageY;
		} else {
			var aCoord = Ext.lib.Dom.getXY(this.getEl());
			this.lastPageX = aCoord[0];
			this.lastPageY = aCoord[1];
		}
	},


	autoScroll: function(x, y, h, w) {

		if (this.scroll) {

			var clientH = Ext.lib.Dom.getViewHeight();


			var clientW = Ext.lib.Dom.getViewWidth();


			var st = this.DDM.getScrollTop();


			var sl = this.DDM.getScrollLeft();


			var bot = h + y;


			var right = w + x;




			var toBot = (clientH + st - y - this.deltaY);


			var toRight = (clientW + sl - x - this.deltaX);




			var thresh = 40;




			var scrAmt = (document.all) ? 80 : 30;



			if ( bot > clientH && toBot < thresh ) {
				window.scrollTo(sl, st + scrAmt);
			}



			if ( y < st && st > 0 && y - st < thresh ) {
				window.scrollTo(sl, st - scrAmt);
			}



			if ( right > clientW && toRight < thresh ) {
				window.scrollTo(sl + scrAmt, st);
			}



			if ( x < sl && sl > 0 && x - sl < thresh ) {
				window.scrollTo(sl - scrAmt, st);
			}
		}
	},


	getTargetCoord: function(iPageX, iPageY) {
		var x = iPageX - this.deltaX;
		var y = iPageY - this.deltaY;

		if (this.constrainX) {
			if (x < this.minX) {
				x = this.minX;
			}
			if (x > this.maxX) {
				x = this.maxX;
			}
		}

		if (this.constrainY) {
			if (y < this.minY) {
				y = this.minY;
			}
			if (y > this.maxY) {
				y = this.maxY;
			}
		}

		x = this.getTick(x, this.xTicks);
		y = this.getTick(y, this.yTicks);


		return {
			x:x,
			y:y
		};
	},


	applyConfig: function() {
		Ext.dd.DD.superclass.applyConfig.call(this);
		this.scroll = (this.config.scroll !== false);
	},


	b4MouseDown: function(e) {

		this.autoOffset(e.getPageX(),
			e.getPageY());
	},


	b4Drag: function(e) {
		this.setDragElPos(e.getPageX(),
			e.getPageY());
	},

	toString: function() {
		return ("DD " + this.id);
	}






});

Ext.dd.DDProxy = function(id, sGroup, config) {
	if (id) {
		this.init(id, sGroup, config);
		this.initFrame();
	}
};


Ext.dd.DDProxy.dragElId = "ygddfdiv";

Ext.extend(Ext.dd.DDProxy, Ext.dd.DD, {


	resizeFrame: true,


	centerFrame: false,


	createFrame: function() {
		var self = this;
		var body = document.body;

		if (!body || !body.firstChild) {
			setTimeout( function() {
				self.createFrame();
			}, 50 );
			return;
		}

		var div = this.getDragEl();

		if (!div) {
			div    = document.createElement("div");
			div.id = this.dragElId;
			var s  = div.style;

			s.position   = "absolute";
			s.visibility = "hidden";
			s.cursor     = "move";
			s.border     = "2px solid #aaa";
			s.zIndex     = 999;




			body.insertBefore(div, body.firstChild);
		}
	},


	initFrame: function() {
		this.createFrame();
	},

	applyConfig: function() {
		Ext.dd.DDProxy.superclass.applyConfig.call(this);

		this.resizeFrame = (this.config.resizeFrame !== false);
		this.centerFrame = (this.config.centerFrame);
		this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId);
	},


	showFrame: function(iPageX, iPageY) {
		var el = this.getEl();
		var dragEl = this.getDragEl();
		var s = dragEl.style;

		this._resizeProxy();

		if (this.centerFrame) {
			this.setDelta( Math.round(parseInt(s.width,  10)/2),
				Math.round(parseInt(s.height, 10)/2) );
		}

		this.setDragElPos(iPageX, iPageY);

		Ext.fly(dragEl).show();
	},


	_resizeProxy: function() {
		if (this.resizeFrame) {
			var el = this.getEl();
			Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight);
		}
	},


	b4MouseDown: function(e) {
		var x = e.getPageX();
		var y = e.getPageY();
		this.autoOffset(x, y);
		this.setDragElPos(x, y);
	},


	b4StartDrag: function(x, y) {

		this.showFrame(x, y);
	},


	b4EndDrag: function(e) {
		Ext.fly(this.getDragEl()).hide();
	},




	endDrag: function(e) {

		var lel = this.getEl();
		var del = this.getDragEl();


		del.style.visibility = "";

		this.beforeMove();


		lel.style.visibility = "hidden";
		Ext.dd.DDM.moveToEl(lel, del);
		del.style.visibility = "hidden";
		lel.style.visibility = "";

		this.afterDrag();
	},

	beforeMove : function(){

	},

	afterDrag : function(){

	},

	toString: function() {
		return ("DDProxy " + this.id);
	}

});

Ext.dd.DDTarget = function(id, sGroup, config) {
	if (id) {
		this.initTarget(id, sGroup, config);
	}
};


Ext.extend(Ext.dd.DDTarget, Ext.dd.DragDrop, {

	getDragEl: Ext.emptyFn,

	isValidHandleChild: Ext.emptyFn,

	startDrag: Ext.emptyFn,

	endDrag: Ext.emptyFn,

	onDrag: Ext.emptyFn,

	onDragDrop: Ext.emptyFn,

	onDragEnter: Ext.emptyFn,

	onDragOut: Ext.emptyFn,

	onDragOver: Ext.emptyFn,

	onInvalidDrop: Ext.emptyFn,

	onMouseDown: Ext.emptyFn,

	onMouseUp: Ext.emptyFn,

	setXConstraint: Ext.emptyFn,

	setYConstraint: Ext.emptyFn,

	resetConstraints: Ext.emptyFn,

	clearConstraints: Ext.emptyFn,

	clearTicks: Ext.emptyFn,

	setInitPosition: Ext.emptyFn,

	setDragElId: Ext.emptyFn,

	setHandleElId: Ext.emptyFn,

	setOuterHandleElId: Ext.emptyFn,

	addInvalidHandleClass: Ext.emptyFn,

	addInvalidHandleId: Ext.emptyFn,

	addInvalidHandleType: Ext.emptyFn,

	removeInvalidHandleClass: Ext.emptyFn,

	removeInvalidHandleId: Ext.emptyFn,

	removeInvalidHandleType: Ext.emptyFn,

	toString: function() {
		return ("DDTarget " + this.id);
	}
});
Ext.dd.DragTracker = Ext.extend(Ext.util.Observable,  {

	active: false,

	tolerance: 5,

	autoStart: false,

	constructor : function(config){
		Ext.apply(this, config);
		this.addEvents(

			'mousedown',

			'mouseup',

			'mousemove',

			'dragstart',

			'dragend',

			'drag'
			);

		this.dragRegion = new Ext.lib.Region(0,0,0,0);

		if(this.el){
			this.initEl(this.el);
		}
		Ext.dd.DragTracker.superclass.constructor.call(this, config);
	},

	initEl: function(el){
		this.el = Ext.get(el);
		el.on('mousedown', this.onMouseDown, this,
			this.delegate ? {
				delegate: this.delegate
				} : undefined);
	},

	destroy : function(){
		this.el.un('mousedown', this.onMouseDown, this);
		delete this.el;
	},

	onMouseDown: function(e, target){
		if(this.fireEvent('mousedown', this, e) !== false && this.onBeforeStart(e) !== false){
			this.startXY = this.lastXY = e.getXY();
			this.dragTarget = this.delegate ? target : this.el.dom;
			if(this.preventDefault !== false){
				e.preventDefault();
			}
			Ext.getDoc().on({
				scope: this,
				mouseup: this.onMouseUp,
				mousemove: this.onMouseMove,
				selectstart: this.stopSelect
			});
			if(this.autoStart){
				this.timer = this.triggerStart.defer(this.autoStart === true ? 1000 : this.autoStart, this, [e]);
			}
		}
	},

	onMouseMove: function(e, target){

		if(this.active && Ext.isIE && !e.browserEvent.button){
			e.preventDefault();
			this.onMouseUp(e);
			return;
		}

		e.preventDefault();
		var xy = e.getXY(), s = this.startXY;
		this.lastXY = xy;
		if(!this.active){
			if(Math.abs(s[0]-xy[0]) > this.tolerance || Math.abs(s[1]-xy[1]) > this.tolerance){
				this.triggerStart(e);
			}else{
				return;
			}
		}
		this.fireEvent('mousemove', this, e);
		this.onDrag(e);
		this.fireEvent('drag', this, e);
	},

	onMouseUp: function(e) {
		var doc = Ext.getDoc(),
		wasActive = this.active;

		doc.un('mousemove', this.onMouseMove, this);
		doc.un('mouseup', this.onMouseUp, this);
		doc.un('selectstart', this.stopSelect, this);
		e.preventDefault();
		this.clearStart();
		this.active = false;
		delete this.elRegion;
		this.fireEvent('mouseup', this, e);
		if(wasActive){
			this.onEnd(e);
			this.fireEvent('dragend', this, e);
		}
	},

	triggerStart: function(e) {
		this.clearStart();
		this.active = true;
		this.onStart(e);
		this.fireEvent('dragstart', this, e);
	},

	clearStart : function() {
		if(this.timer){
			clearTimeout(this.timer);
			delete this.timer;
		}
	},

	stopSelect : function(e) {
		e.stopEvent();
		return false;
	},


	onBeforeStart : function(e) {

	},


	onStart : function(xy) {

	},


	onDrag : function(e) {

	},


	onEnd : function(e) {

	},


	getDragTarget : function(){
		return this.dragTarget;
	},

	getDragCt : function(){
		return this.el;
	},

	getXY : function(constrain){
		return constrain ?
		this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY;
	},

	getOffset : function(constrain){
		var xy = this.getXY(constrain),
		s = this.startXY;
		return [s[0]-xy[0], s[1]-xy[1]];
	},

	constrainModes: {
		'point' : function(xy){

			if(!this.elRegion){
				this.elRegion = this.getDragCt().getRegion();
			}

			var dr = this.dragRegion;

			dr.left = xy[0];
			dr.top = xy[1];
			dr.right = xy[0];
			dr.bottom = xy[1];

			dr.constrainTo(this.elRegion);

			return [dr.left, dr.top];
		}
	}
});
Ext.dd.ScrollManager = function(){
	var ddm = Ext.dd.DragDropMgr;
	var els = {};
	var dragEl = null;
	var proc = {};

	var onStop = function(e){
		dragEl = null;
		clearProc();
	};

	var triggerRefresh = function(){
		if(ddm.dragCurrent){
			ddm.refreshCache(ddm.dragCurrent.groups);
		}
	};

	var doScroll = function(){
		if(ddm.dragCurrent){
			var dds = Ext.dd.ScrollManager;
			var inc = proc.el.ddScrollConfig ?
			proc.el.ddScrollConfig.increment : dds.increment;
			if(!dds.animate){
				if(proc.el.scroll(proc.dir, inc)){
					triggerRefresh();
				}
			}else{
				proc.el.scroll(proc.dir, inc, true, dds.animDuration, triggerRefresh);
			}
		}
	};

	var clearProc = function(){
		if(proc.id){
			clearInterval(proc.id);
		}
		proc.id = 0;
		proc.el = null;
		proc.dir = "";
	};

	var startProc = function(el, dir){
		clearProc();
		proc.el = el;
		proc.dir = dir;
		var group = el.ddScrollConfig ? el.ddScrollConfig.ddGroup : undefined,
		freq  = (el.ddScrollConfig && el.ddScrollConfig.frequency)
		? el.ddScrollConfig.frequency
		: Ext.dd.ScrollManager.frequency;

		if (group === undefined || ddm.dragCurrent.ddGroup == group) {
			proc.id = setInterval(doScroll, freq);
		}
	};

	var onFire = function(e, isDrop){
		if(isDrop || !ddm.dragCurrent){
			return;
		}
		var dds = Ext.dd.ScrollManager;
		if(!dragEl || dragEl != ddm.dragCurrent){
			dragEl = ddm.dragCurrent;

			dds.refreshCache();
		}

		var xy = Ext.lib.Event.getXY(e);
		var pt = new Ext.lib.Point(xy[0], xy[1]);
		for(var id in els){
			var el = els[id], r = el._region;
			var c = el.ddScrollConfig ? el.ddScrollConfig : dds;
			if(r && r.contains(pt) && el.isScrollable()){
				if(r.bottom - pt.y <= c.vthresh){
					if(proc.el != el){
						startProc(el, "down");
					}
					return;
				}else if(r.right - pt.x <= c.hthresh){
					if(proc.el != el){
						startProc(el, "left");
					}
					return;
				}else if(pt.y - r.top <= c.vthresh){
					if(proc.el != el){
						startProc(el, "up");
					}
					return;
				}else if(pt.x - r.left <= c.hthresh){
					if(proc.el != el){
						startProc(el, "right");
					}
					return;
				}
			}
		}
		clearProc();
	};

	ddm.fireEvents = ddm.fireEvents.createSequence(onFire, ddm);
	ddm.stopDrag = ddm.stopDrag.createSequence(onStop, ddm);

	return {

		register : function(el){
			if(Ext.isArray(el)){
				for(var i = 0, len = el.length; i < len; i++) {
					this.register(el[i]);
				}
			}else{
				el = Ext.get(el);
				els[el.id] = el;
			}
		},


		unregister : function(el){
			if(Ext.isArray(el)){
				for(var i = 0, len = el.length; i < len; i++) {
					this.unregister(el[i]);
				}
			}else{
				el = Ext.get(el);
				delete els[el.id];
			}
		},


		vthresh : 25,

		hthresh : 25,


		increment : 100,


		frequency : 500,


		animate: true,


		animDuration: .4,


		ddGroup: undefined,


		refreshCache : function(){
			for(var id in els){
				if(typeof els[id] == 'object'){
					els[id]._region = els[id].getRegion();
				}
			}
		}
	};
}();
Ext.dd.Registry = function(){
	var elements = {};
	var handles = {};
	var autoIdSeed = 0;

	var getId = function(el, autogen){
		if(typeof el == "string"){
			return el;
		}
		var id = el.id;
		if(!id && autogen !== false){
			id = "extdd-" + (++autoIdSeed);
			el.id = id;
		}
		return id;
	};

	return {

		register : function(el, data){
			data = data || {};
			if(typeof el == "string"){
				el = document.getElementById(el);
			}
			data.ddel = el;
			elements[getId(el)] = data;
			if(data.isHandle !== false){
				handles[data.ddel.id] = data;
			}
			if(data.handles){
				var hs = data.handles;
				for(var i = 0, len = hs.length; i < len; i++){
					handles[getId(hs[i])] = data;
				}
			}
		},


		unregister : function(el){
			var id = getId(el, false);
			var data = elements[id];
			if(data){
				delete elements[id];
				if(data.handles){
					var hs = data.handles;
					for(var i = 0, len = hs.length; i < len; i++){
						delete handles[getId(hs[i], false)];
					}
				}
			}
		},


		getHandle : function(id){
			if(typeof id != "string"){
				id = id.id;
			}
			return handles[id];
		},


		getHandleFromEvent : function(e){
			var t = Ext.lib.Event.getTarget(e);
			return t ? handles[t.id] : null;
		},


		getTarget : function(id){
			if(typeof id != "string"){
				id = id.id;
			}
			return elements[id];
		},


		getTargetFromEvent : function(e){
			var t = Ext.lib.Event.getTarget(e);
			return t ? elements[t.id] || handles[t.id] : null;
		}
	};
}();
Ext.dd.StatusProxy = function(config){
	Ext.apply(this, config);
	this.id = this.id || Ext.id();
	this.el = new Ext.Layer({
		dh: {
			id: this.id,
			tag: "div",
			cls: "x-dd-drag-proxy "+this.dropNotAllowed,
			children: [

			{
				tag: "div",
				cls: "x-dd-drop-icon"
			},

			{
				tag: "div",
				cls: "x-dd-drag-ghost"
			}
			]
		},
		shadow: !config || config.shadow !== false
	});
	this.ghost = Ext.get(this.el.dom.childNodes[1]);
	this.dropStatus = this.dropNotAllowed;
};

Ext.dd.StatusProxy.prototype = {

	dropAllowed : "x-dd-drop-ok",

	dropNotAllowed : "x-dd-drop-nodrop",


	setStatus : function(cssClass){
		cssClass = cssClass || this.dropNotAllowed;
		if(this.dropStatus != cssClass){
			this.el.replaceClass(this.dropStatus, cssClass);
			this.dropStatus = cssClass;
		}
	},


	reset : function(clearGhost){
		this.el.dom.className = "x-dd-drag-proxy " + this.dropNotAllowed;
		this.dropStatus = this.dropNotAllowed;
		if(clearGhost){
			this.ghost.update("");
		}
	},


	update : function(html){
		if(typeof html == "string"){
			this.ghost.update(html);
		}else{
			this.ghost.update("");
			html.style.margin = "0";
			this.ghost.dom.appendChild(html);
		}
		var el = this.ghost.dom.firstChild;
		if(el){
			Ext.fly(el).setStyle('float', 'none');
		}
	},


	getEl : function(){
		return this.el;
	},


	getGhost : function(){
		return this.ghost;
	},


	hide : function(clear){
		this.el.hide();
		if(clear){
			this.reset(true);
		}
	},


	stop : function(){
		if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){
			this.anim.stop();
		}
	},


	show : function(){
		this.el.show();
	},


	sync : function(){
		this.el.sync();
	},


	repair : function(xy, callback, scope){
		this.callback = callback;
		this.scope = scope;
		if(xy && this.animRepair !== false){
			this.el.addClass("x-dd-drag-repair");
			this.el.hideUnders(true);
			this.anim = this.el.shift({
				duration: this.repairDuration || .5,
				easing: 'easeOut',
				xy: xy,
				stopFx: true,
				callback: this.afterRepair,
				scope: this
			});
		}else{
			this.afterRepair();
		}
	},


	afterRepair : function(){
		this.hide(true);
		if(typeof this.callback == "function"){
			this.callback.call(this.scope || this);
		}
		this.callback = null;
		this.scope = null;
	},

	destroy: function(){
		Ext.destroy(this.ghost, this.el);
	}
};
Ext.dd.DragSource = function(el, config){
	this.el = Ext.get(el);
	if(!this.dragData){
		this.dragData = {};
	}

	Ext.apply(this, config);

	if(!this.proxy){
		this.proxy = new Ext.dd.StatusProxy();
	}
	Ext.dd.DragSource.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
	{
		dragElId : this.proxy.id,
		resizeFrame: false,
		isTarget: false,
		scroll: this.scroll === true
		});

	this.dragging = false;
};

Ext.extend(Ext.dd.DragSource, Ext.dd.DDProxy, {


	dropAllowed : "x-dd-drop-ok",

	dropNotAllowed : "x-dd-drop-nodrop",


	getDragData : function(e){
		return this.dragData;
	},


	onDragEnter : function(e, id){
		var target = Ext.dd.DragDropMgr.getDDById(id);
		this.cachedTarget = target;
		if(this.beforeDragEnter(target, e, id) !== false){
			if(target.isNotifyTarget){
				var status = target.notifyEnter(this, e, this.dragData);
				this.proxy.setStatus(status);
			}else{
				this.proxy.setStatus(this.dropAllowed);
			}

			if(this.afterDragEnter){

				this.afterDragEnter(target, e, id);
			}
		}
	},


	beforeDragEnter : function(target, e, id){
		return true;
	},


	alignElWithMouse: function() {
		Ext.dd.DragSource.superclass.alignElWithMouse.apply(this, arguments);
		this.proxy.sync();
	},


	onDragOver : function(e, id){
		var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
		if(this.beforeDragOver(target, e, id) !== false){
			if(target.isNotifyTarget){
				var status = target.notifyOver(this, e, this.dragData);
				this.proxy.setStatus(status);
			}

			if(this.afterDragOver){

				this.afterDragOver(target, e, id);
			}
		}
	},


	beforeDragOver : function(target, e, id){
		return true;
	},


	onDragOut : function(e, id){
		var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
		if(this.beforeDragOut(target, e, id) !== false){
			if(target.isNotifyTarget){
				target.notifyOut(this, e, this.dragData);
			}
			this.proxy.reset();
			if(this.afterDragOut){

				this.afterDragOut(target, e, id);
			}
		}
		this.cachedTarget = null;
	},


	beforeDragOut : function(target, e, id){
		return true;
	},


	onDragDrop : function(e, id){
		var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
		if(this.beforeDragDrop(target, e, id) !== false){
			if(target.isNotifyTarget){
				if(target.notifyDrop(this, e, this.dragData)){
					this.onValidDrop(target, e, id);
				}else{
					this.onInvalidDrop(target, e, id);
				}
			}else{
				this.onValidDrop(target, e, id);
			}

			if(this.afterDragDrop){

				this.afterDragDrop(target, e, id);
			}
		}
		delete this.cachedTarget;
	},


	beforeDragDrop : function(target, e, id){
		return true;
	},


	onValidDrop : function(target, e, id){
		this.hideProxy();
		if(this.afterValidDrop){

			this.afterValidDrop(target, e, id);
		}
	},


	getRepairXY : function(e, data){
		return this.el.getXY();
	},


	onInvalidDrop : function(target, e, id){
		this.beforeInvalidDrop(target, e, id);
		if(this.cachedTarget){
			if(this.cachedTarget.isNotifyTarget){
				this.cachedTarget.notifyOut(this, e, this.dragData);
			}
			this.cacheTarget = null;
		}
		this.proxy.repair(this.getRepairXY(e, this.dragData), this.afterRepair, this);

		if(this.afterInvalidDrop){

			this.afterInvalidDrop(e, id);
		}
	},


	afterRepair : function(){
		if(Ext.enableFx){
			this.el.highlight(this.hlColor || "c3daf9");
		}
		this.dragging = false;
	},


	beforeInvalidDrop : function(target, e, id){
		return true;
	},


	handleMouseDown : function(e){
		if(this.dragging) {
			return;
		}
		var data = this.getDragData(e);
		if(data && this.onBeforeDrag(data, e) !== false){
			this.dragData = data;
			this.proxy.stop();
			Ext.dd.DragSource.superclass.handleMouseDown.apply(this, arguments);
		}
	},


	onBeforeDrag : function(data, e){
		return true;
	},


	onStartDrag : Ext.emptyFn,


	startDrag : function(x, y){
		this.proxy.reset();
		this.dragging = true;
		this.proxy.update("");
		this.onInitDrag(x, y);
		this.proxy.show();
	},


	onInitDrag : function(x, y){
		var clone = this.el.dom.cloneNode(true);
		clone.id = Ext.id();
		this.proxy.update(clone);
		this.onStartDrag(x, y);
		return true;
	},


	getProxy : function(){
		return this.proxy;
	},


	hideProxy : function(){
		this.proxy.hide();
		this.proxy.reset(true);
		this.dragging = false;
	},


	triggerCacheRefresh : function(){
		Ext.dd.DDM.refreshCache(this.groups);
	},


	b4EndDrag: function(e) {
	},


	endDrag : function(e){
		this.onEndDrag(this.dragData, e);
	},


	onEndDrag : function(data, e){
	},


	autoOffset : function(x, y) {
		this.setDelta(-12, -20);
	},

	destroy: function(){
		Ext.dd.DragSource.superclass.destroy.call(this);
		Ext.destroy(this.proxy);
	}
});
Ext.dd.DropTarget = Ext.extend(Ext.dd.DDTarget, {

	constructor : function(el, config){
		this.el = Ext.get(el);

		Ext.apply(this, config);

		if(this.containerScroll){
			Ext.dd.ScrollManager.register(this.el);
		}

		Ext.dd.DropTarget.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
		{
			isTarget: true
		});
	},




	dropAllowed : "x-dd-drop-ok",

	dropNotAllowed : "x-dd-drop-nodrop",


	isTarget : true,


	isNotifyTarget : true,


	notifyEnter : function(dd, e, data){
		if(this.overClass){
			this.el.addClass(this.overClass);
		}
		return this.dropAllowed;
	},


	notifyOver : function(dd, e, data){
		return this.dropAllowed;
	},


	notifyOut : function(dd, e, data){
		if(this.overClass){
			this.el.removeClass(this.overClass);
		}
	},


	notifyDrop : function(dd, e, data){
		return false;
	},

	destroy : function(){
		Ext.dd.DropTarget.superclass.destroy.call(this);
		if(this.containerScroll){
			Ext.dd.ScrollManager.unregister(this.el);
		}
	}
});
Ext.dd.DragZone = Ext.extend(Ext.dd.DragSource, {

	constructor : function(el, config){
		Ext.dd.DragZone.superclass.constructor.call(this, el, config);
		if(this.containerScroll){
			Ext.dd.ScrollManager.register(this.el);
		}
	},






	getDragData : function(e){
		return Ext.dd.Registry.getHandleFromEvent(e);
	},


	onInitDrag : function(x, y){
		this.proxy.update(this.dragData.ddel.cloneNode(true));
		this.onStartDrag(x, y);
		return true;
	},


	afterRepair : function(){
		if(Ext.enableFx){
			Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
		}
		this.dragging = false;
	},


	getRepairXY : function(e){
		return Ext.Element.fly(this.dragData.ddel).getXY();
	},

	destroy : function(){
		Ext.dd.DragZone.superclass.destroy.call(this);
		if(this.containerScroll){
			Ext.dd.ScrollManager.unregister(this.el);
		}
	}
});
Ext.dd.DropZone = function(el, config){
	Ext.dd.DropZone.superclass.constructor.call(this, el, config);
};

Ext.extend(Ext.dd.DropZone, Ext.dd.DropTarget, {

	getTargetFromEvent : function(e){
		return Ext.dd.Registry.getTargetFromEvent(e);
	},


	onNodeEnter : function(n, dd, e, data){

	},


	onNodeOver : function(n, dd, e, data){
		return this.dropAllowed;
	},


	onNodeOut : function(n, dd, e, data){

	},


	onNodeDrop : function(n, dd, e, data){
		return false;
	},


	onContainerOver : function(dd, e, data){
		return this.dropNotAllowed;
	},


	onContainerDrop : function(dd, e, data){
		return false;
	},


	notifyEnter : function(dd, e, data){
		return this.dropNotAllowed;
	},


	notifyOver : function(dd, e, data){
		var n = this.getTargetFromEvent(e);
		if(!n){
			if(this.lastOverNode){
				this.onNodeOut(this.lastOverNode, dd, e, data);
				this.lastOverNode = null;
			}
			return this.onContainerOver(dd, e, data);
		}
		if(this.lastOverNode != n){
			if(this.lastOverNode){
				this.onNodeOut(this.lastOverNode, dd, e, data);
			}
			this.onNodeEnter(n, dd, e, data);
			this.lastOverNode = n;
		}
		return this.onNodeOver(n, dd, e, data);
	},


	notifyOut : function(dd, e, data){
		if(this.lastOverNode){
			this.onNodeOut(this.lastOverNode, dd, e, data);
			this.lastOverNode = null;
		}
	},


	notifyDrop : function(dd, e, data){
		if(this.lastOverNode){
			this.onNodeOut(this.lastOverNode, dd, e, data);
			this.lastOverNode = null;
		}
		var n = this.getTargetFromEvent(e);
		return n ?
		this.onNodeDrop(n, dd, e, data) :
		this.onContainerDrop(dd, e, data);
	},


	triggerCacheRefresh : function(){
		Ext.dd.DDM.refreshCache(this.groups);
	}
});
Ext.Element.addMethods({

	initDD : function(group, config, overrides){
		var dd = new Ext.dd.DD(Ext.id(this.dom), group, config);
		return Ext.apply(dd, overrides);
	},


	initDDProxy : function(group, config, overrides){
		var dd = new Ext.dd.DDProxy(Ext.id(this.dom), group, config);
		return Ext.apply(dd, overrides);
	},


	initDDTarget : function(group, config, overrides){
		var dd = new Ext.dd.DDTarget(Ext.id(this.dom), group, config);
		return Ext.apply(dd, overrides);
	}
});

Ext.data.Api = (function() {





	var validActions = {};

	return {

		actions : {
			create  : 'create',
			read    : 'read',
			update  : 'update',
			destroy : 'destroy'
		},


		restActions : {
			create  : 'POST',
			read    : 'GET',
			update  : 'PUT',
			destroy : 'DELETE'
		},


		isAction : function(action) {
			return (Ext.data.Api.actions[action]) ? true : false;
		},


		getVerb : function(name) {
			if (validActions[name]) {
				return validActions[name];
			}
			for (var verb in this.actions) {
				if (this.actions[verb] === name) {
					validActions[name] = verb;
					break;
				}
			}
			return (validActions[name] !== undefined) ? validActions[name] : null;
		},


		isValid : function(api){
			var invalid = [];
			var crud = this.actions;
			for (var action in api) {
				if (!(action in crud)) {
					invalid.push(action);
				}
			}
			return (!invalid.length) ? true : invalid;
		},


		hasUniqueUrl : function(proxy, verb) {
			var url = (proxy.api[verb]) ? proxy.api[verb].url : null;
			var unique = true;
			for (var action in proxy.api) {
				if ((unique = (action === verb) ? true : (proxy.api[action].url != url) ? true : false) === false) {
					break;
				}
			}
			return unique;
		},


		prepare : function(proxy) {
			if (!proxy.api) {
				proxy.api = {};
			}
			for (var verb in this.actions) {
				var action = this.actions[verb];
				proxy.api[action] = proxy.api[action] || proxy.url || proxy.directFn;
				if (typeof(proxy.api[action]) == 'string') {
					proxy.api[action] = {
						url: proxy.api[action],
						method: (proxy.restful === true) ? Ext.data.Api.restActions[action] : undefined
					};
				}
			}
		},


		restify : function(proxy) {
			proxy.restful = true;
			for (var verb in this.restActions) {
				proxy.api[this.actions[verb]].method ||
				(proxy.api[this.actions[verb]].method = this.restActions[verb]);
			}


			proxy.onWrite = proxy.onWrite.createInterceptor(function(action, o, response, rs) {
				var reader = o.reader;
				var res = new Ext.data.Response({
					action: action,
					raw: response
				});

				switch (response.status) {
					case 200:
						return true;
						break;
					case 201:
						if (Ext.isEmpty(res.raw.responseText)) {
							res.success = true;
						} else {

							return true;
						}
						break;
					case 204:
						res.success = true;
						res.data = null;
						break;
					default:
						return true;
						break;
				}
				if (res.success === true) {
					this.fireEvent("write", this, action, res.data, res, rs, o.request.arg);
				} else {
					this.fireEvent('exception', this, 'remote', action, o, res, rs);
				}
				o.request.callback.call(o.request.scope, res.data, res, res.success);

				return false;
			}, proxy);
		}
	};
})();


Ext.data.Response = function(params, response) {
	Ext.apply(this, params, {
		raw: response
	});
};
Ext.data.Response.prototype = {
	message : null,
	success : false,
	status : null,
	root : null,
	raw : null,

	getMessage : function() {
		return this.message;
	},
	getSuccess : function() {
		return this.success;
	},
	getStatus : function() {
		return this.status;
	},
	getRoot : function() {
		return this.root;
	},
	getRawResponse : function() {
		return this.raw;
	}
};


Ext.data.Api.Error = Ext.extend(Ext.Error, {
	constructor : function(message, arg) {
		this.arg = arg;
		Ext.Error.call(this, message);
	},
	name: 'Ext.data.Api'
});
Ext.apply(Ext.data.Api.Error.prototype, {
	lang: {
		'action-url-undefined': 'No fallback url defined for this action.  When defining a DataProxy api, please be sure to define an url for each CRUD action in Ext.data.Api.actions or define a default url in addition to your api-configuration.',
		'invalid': 'received an invalid API-configuration.  Please ensure your proxy API-configuration contains only the actions defined in Ext.data.Api.actions',
		'invalid-url': 'Invalid url.  Please review your proxy configuration.',
		'execute': 'Attempted to execute an unknown action.  Valid API actions are defined in Ext.data.Api.actions"'
	}
});




Ext.data.SortTypes = {

	none : function(s){
		return s;
	},


	stripTagsRE : /<\/?[^>]+>/gi,


	asText : function(s){
		return String(s).replace(this.stripTagsRE, "");
	},


	asUCText : function(s){
		return String(s).toUpperCase().replace(this.stripTagsRE, "");
	},


	asUCString : function(s) {
		return String(s).toUpperCase();
	},


	asDate : function(s) {
		if(!s){
			return 0;
		}
		if(Ext.isDate(s)){
			return s.getTime();
		}
		return Date.parse(String(s));
	},


	asFloat : function(s) {
		var val = parseFloat(String(s).replace(/,/g, ""));
		return isNaN(val) ? 0 : val;
	},


	asInt : function(s) {
		var val = parseInt(String(s).replace(/,/g, ""), 10);
		return isNaN(val) ? 0 : val;
	}
};
Ext.data.Record = function(data, id){

	this.id = (id || id === 0) ? id : Ext.data.Record.id(this);
	this.data = data || {};
};


Ext.data.Record.create = function(o){
	var f = Ext.extend(Ext.data.Record, {});
	var p = f.prototype;
	p.fields = new Ext.util.MixedCollection(false, function(field){
		return field.name;
	});
	for(var i = 0, len = o.length; i < len; i++){
		p.fields.add(new Ext.data.Field(o[i]));
	}
	f.getField = function(name){
		return p.fields.get(name);
	};
	return f;
};

Ext.data.Record.PREFIX = 'ext-record';
Ext.data.Record.AUTO_ID = 1;
Ext.data.Record.EDIT = 'edit';
Ext.data.Record.REJECT = 'reject';
Ext.data.Record.COMMIT = 'commit';



Ext.data.Record.id = function(rec) {
	rec.phantom = true;
	return [Ext.data.Record.PREFIX, '-', Ext.data.Record.AUTO_ID++].join('');
};

Ext.data.Record.prototype = {






	dirty : false,
	editing : false,
	error : null,

	modified : null,

	phantom : false,


	join : function(store){

		this.store = store;
	},


	set : function(name, value){
		var encode = Ext.isPrimitive(value) ? String : Ext.encode;
		if(encode(this.data[name]) == encode(value)) {
			return;
		}
		this.dirty = true;
		if(!this.modified){
			this.modified = {};
		}
		if(this.modified[name] === undefined){
			this.modified[name] = this.data[name];
		}
		this.data[name] = value;
		if(!this.editing){
			this.afterEdit();
		}
	},


	afterEdit : function(){
		if (this.store != undefined && typeof this.store.afterEdit == "function") {
			this.store.afterEdit(this);
		}
	},


	afterReject : function(){
		if(this.store){
			this.store.afterReject(this);
		}
	},


	afterCommit : function(){
		if(this.store){
			this.store.afterCommit(this);
		}
	},


	get : function(name){
		return this.data[name];
	},


	beginEdit : function(){
		this.editing = true;
		this.modified = this.modified || {};
	},


	cancelEdit : function(){
		this.editing = false;
		delete this.modified;
	},


	endEdit : function(){
		this.editing = false;
		if(this.dirty){
			this.afterEdit();
		}
	},


	reject : function(silent){
		var m = this.modified;
		for(var n in m){
			if(typeof m[n] != "function"){
				this.data[n] = m[n];
			}
		}
		this.dirty = false;
		delete this.modified;
		this.editing = false;
		if(silent !== true){
			this.afterReject();
		}
	},


	commit : function(silent){
		this.dirty = false;
		delete this.modified;
		this.editing = false;
		if(silent !== true){
			this.afterCommit();
		}
	},


	getChanges : function(){
		var m = this.modified, cs = {};
		for(var n in m){
			if(m.hasOwnProperty(n)){
				cs[n] = this.data[n];
			}
		}
		return cs;
	},


	hasError : function(){
		return this.error !== null;
	},


	clearError : function(){
		this.error = null;
	},


	copy : function(newId) {
		return new this.constructor(Ext.apply({}, this.data), newId || this.id);
	},


	isModified : function(fieldName){
		return !!(this.modified && this.modified.hasOwnProperty(fieldName));
	},


	isValid : function() {
		return this.fields.find(function(f) {
			return (f.allowBlank === false && Ext.isEmpty(this.data[f.name])) ? true : false;
		},this) ? false : true;
	},


	markDirty : function(){
		this.dirty = true;
		if(!this.modified){
			this.modified = {};
		}
		this.fields.each(function(f) {
			this.modified[f.name] = this.data[f.name];
		},this);
	}
};

Ext.StoreMgr = Ext.apply(new Ext.util.MixedCollection(), {



	register : function(){
		for(var i = 0, s; (s = arguments[i]); i++){
			this.add(s);
		}
	},


	unregister : function(){
		for(var i = 0, s; (s = arguments[i]); i++){
			this.remove(this.lookup(s));
		}
	},


	lookup : function(id){
		if(Ext.isArray(id)){
			var fields = ['field1'], expand = !Ext.isArray(id[0]);
			if(!expand){
				for(var i = 2, len = id[0].length; i <= len; ++i){
					fields.push('field' + i);
				}
			}
			return new Ext.data.ArrayStore({
				fields: fields,
				data: id,
				expandData: expand,
				autoDestroy: true,
				autoCreated: true

			});
		}
		return Ext.isObject(id) ? (id.events ? id : Ext.create(id, 'store')) : this.get(id);
	},


	getKey : function(o){
		return o.storeId;
	}
});
Ext.data.Store = Ext.extend(Ext.util.Observable, {







	writer : undefined,



	remoteSort : false,


	autoDestroy : false,


	pruneModifiedRecords : false,


	lastOptions : null,


	autoSave : true,


	batch : true,


	restful: false,


	paramNames : undefined,


	defaultParamNames : {
		start : 'start',
		limit : 'limit',
		sort : 'sort',
		dir : 'dir'
	},

	isDestroyed: false,
	hasMultiSort: false,


	batchKey : '_ext_batch_',

	constructor : function(config){




		this.data = new Ext.util.MixedCollection(false);
		this.data.getKey = function(o){
			return o.id;
		};



		this.removed = [];

		if(config && config.data){
			this.inlineData = config.data;
			delete config.data;
		}

		Ext.apply(this, config);


		this.baseParams = Ext.isObject(this.baseParams) ? this.baseParams : {};

		this.paramNames = Ext.applyIf(this.paramNames || {}, this.defaultParamNames);

		if((this.url || this.api) && !this.proxy){
			this.proxy = new Ext.data.HttpProxy({
				url: this.url,
				api: this.api
				});
		}

		if (this.restful === true && this.proxy) {


			this.batch = false;
			Ext.data.Api.restify(this.proxy);
		}

		if(this.reader){
			if(!this.recordType){
				this.recordType = this.reader.recordType;
			}
			if(this.reader.onMetaChange){
				this.reader.onMetaChange = this.reader.onMetaChange.createSequence(this.onMetaChange, this);
			}
			if (this.writer) {
				if (this.writer instanceof(Ext.data.DataWriter) === false) {
					this.writer = this.buildWriter(this.writer);
				}
				this.writer.meta = this.reader.meta;
				this.pruneModifiedRecords = true;
			}
		}



		if(this.recordType){

			this.fields = this.recordType.prototype.fields;
		}
		this.modified = [];

		this.addEvents(

			'datachanged',

			'metachange',

			'add',

			'remove',

			'update',

			'clear',

			'exception',

			'beforeload',

			'load',

			'loadexception',

			'beforewrite',

			'write',

			'beforesave',

			'save'

			);

		if(this.proxy){

			this.relayEvents(this.proxy,  ['loadexception', 'exception']);
		}

		if (this.writer) {
			this.on({
				scope: this,
				add: this.createRecords,
				remove: this.destroyRecord,
				update: this.updateRecord,
				clear: this.onClear
			});
		}

		this.sortToggle = {};
		if(this.sortField){
			this.setDefaultSort(this.sortField, this.sortDir);
		}else if(this.sortInfo){
			this.setDefaultSort(this.sortInfo.field, this.sortInfo.direction);
		}

		Ext.data.Store.superclass.constructor.call(this);

		if(this.id){
			this.storeId = this.id;
			delete this.id;
		}
		if(this.storeId){
			Ext.StoreMgr.register(this);
		}
		if(this.inlineData){
			this.loadData(this.inlineData);
			delete this.inlineData;
		}else if(this.autoLoad){
			this.load.defer(10, this, [
				typeof this.autoLoad == 'object' ?
				this.autoLoad : undefined]);
		}

		this.batchCounter = 0;
		this.batches = {};
	},


	buildWriter : function(config) {
		var klass = undefined,
		type = (config.format || 'json').toLowerCase();
		switch (type) {
			case 'json':
				klass = Ext.data.JsonWriter;
				break;
			case 'xml':
				klass = Ext.data.XmlWriter;
				break;
			default:
				klass = Ext.data.JsonWriter;
		}
		return new klass(config);
	},


	destroy : function(){
		if(!this.isDestroyed){
			if(this.storeId){
				Ext.StoreMgr.unregister(this);
			}
			this.clearData();
			this.data = null;
			Ext.destroy(this.proxy);
			this.reader = this.writer = null;
			this.purgeListeners();
			this.isDestroyed = true;
		}
	},


	add : function(records) {
		var i, len, record, index;

		records = [].concat(records);
		if (records.length < 1) {
			return;
		}

		for (i = 0, len = records.length; i < len; i++) {
			record = records[i];

			record.join(this);

			if (record.dirty || record.phantom) {
				this.modified.push(record);
			}
		}

		index = this.data.length;
		this.data.addAll(records);

		if (this.snapshot) {
			this.snapshot.addAll(records);
		}

		this.fireEvent('add', this, records, index);
	},


	addSorted : function(record){
		var index = this.findInsertIndex(record);
		this.insert(index, record);
	},


	doUpdate : function(rec){
		this.data.replace(rec.id, rec);
		if(this.snapshot){
			this.snapshot.replace(rec.id, rec);
		}
		this.fireEvent('update', this, rec, Ext.data.Record.COMMIT);
	},


	remove : function(record){
		if(Ext.isArray(record)){
			Ext.each(record, function(r){
				this.remove(r);
			}, this);
			return;
		}
		var index = this.data.indexOf(record);
		if(index > -1){
			record.join(null);
			this.data.removeAt(index);
		}
		if(this.pruneModifiedRecords){
			this.modified.remove(record);
		}
		if(this.snapshot){
			this.snapshot.remove(record);
		}
		if(index > -1){
			this.fireEvent('remove', this, record, index);
		}
	},


	removeAt : function(index){
		this.remove(this.getAt(index));
	},


	removeAll : function(silent){
		var items = [];
		this.each(function(rec){
			items.push(rec);
		});
		this.clearData();
		if(this.snapshot){
			this.snapshot.clear();
		}
		if(this.pruneModifiedRecords){
			this.modified = [];
		}
		if (silent !== true) {
			this.fireEvent('clear', this, items);
		}
	},


	onClear: function(store, records){
		Ext.each(records, function(rec, index){
			this.destroyRecord(this, rec, index);
		}, this);
	},


	insert : function(index, records) {
		var i, len, record;

		records = [].concat(records);
		for (i = 0, len = records.length; i < len; i++) {
			record = records[i];

			this.data.insert(index + i, record);
			record.join(this);

			if (record.dirty || record.phantom) {
				this.modified.push(record);
			}
		}

		if (this.snapshot) {
			this.snapshot.addAll(records);
		}

		this.fireEvent('add', this, records, index);
	},


	indexOf : function(record){
		return this.data.indexOf(record);
	},


	indexOfId : function(id){
		return this.data.indexOfKey(id);
	},


	getById : function(id){
		return (this.snapshot || this.data).key(id);
	},


	getAt : function(index){
		return this.data.itemAt(index);
	},


	getRange : function(start, end){
		return this.data.getRange(start, end);
	},


	storeOptions : function(o){
		o = Ext.apply({}, o);
		delete o.callback;
		delete o.scope;
		this.lastOptions = o;
	},


	clearData: function(){
		this.data.each(function(rec) {
			rec.join(null);
		});
		this.data.clear();
	},


	load : function(options) {
		options = Ext.apply({}, options);
		this.storeOptions(options);
		if(this.sortInfo && this.remoteSort){
			var pn = this.paramNames;
			options.params = Ext.apply({}, options.params);
			options.params[pn.sort] = this.sortInfo.field;
			options.params[pn.dir] = this.sortInfo.direction;
		}
		try {
			return this.execute('read', null, options);
		} catch(e) {
			this.handleException(e);
			return false;
		}
	},


	updateRecord : function(store, record, action) {
		if (action == Ext.data.Record.EDIT && this.autoSave === true && (!record.phantom || (record.phantom && record.isValid()))) {
			this.save();
		}
	},


	createRecords : function(store, records, index) {
		var modified = this.modified,
		length   = records.length,
		record, i;

		for (i = 0; i < length; i++) {
			record = records[i];

			if (record.phantom && record.isValid()) {
				record.markDirty();

				if (modified.indexOf(record) == -1) {
					modified.push(record);
				}
			}
		}
		if (this.autoSave === true) {
			this.save();
		}
	},


	destroyRecord : function(store, record, index) {
		if (this.modified.indexOf(record) != -1) {
			this.modified.remove(record);
		}
		if (!record.phantom) {
			this.removed.push(record);




			record.lastIndex = index;

			if (this.autoSave === true) {
				this.save();
			}
		}
	},


	execute : function(action, rs, options,  batch) {

		if (!Ext.data.Api.isAction(action)) {
			throw new Ext.data.Api.Error('execute', action);
		}

		options = Ext.applyIf(options||{}, {
			params: {}
		});
		if(batch !== undefined){
			this.addToBatch(batch);
		}


		var doRequest = true;

		if (action === 'read') {
			doRequest = this.fireEvent('beforeload', this, options);
			Ext.applyIf(options.params, this.baseParams);
		}
		else {


			if (this.writer.listful === true && this.restful !== true) {
				rs = (Ext.isArray(rs)) ? rs : [rs];
			}

			else if (Ext.isArray(rs) && rs.length == 1) {
				rs = rs.shift();
			}

			if ((doRequest = this.fireEvent('beforewrite', this, action, rs, options)) !== false) {
				this.writer.apply(options.params, this.baseParams, action, rs);
			}
		}
		if (doRequest !== false) {

			if (this.writer && this.proxy.url && !this.proxy.restful && !Ext.data.Api.hasUniqueUrl(this.proxy, action)) {
				options.params.xaction = action;
			}





			this.proxy.request(Ext.data.Api.actions[action], rs, options.params, this.reader, this.createCallback(action, rs, batch), this, options);
		}
		return doRequest;
	},


	save : function() {
		if (!this.writer) {
			throw new Ext.data.Store.Error('writer-undefined');
		}

		var queue = [],
		len,
		trans,
		batch,
		data = {},
		i;

		if(this.removed.length){
			queue.push(['destroy', this.removed]);
		}


		var rs = [].concat(this.getModifiedRecords());
		if(rs.length){

			var phantoms = [];
			for(i = rs.length-1; i >= 0; i--){
				if(rs[i].phantom === true){
					var rec = rs.splice(i, 1).shift();
					if(rec.isValid()){
						phantoms.push(rec);
					}
				}else if(!rs[i].isValid()){
					rs.splice(i,1);
				}
			}

			if(phantoms.length){
				queue.push(['create', phantoms]);
			}


			if(rs.length){
				queue.push(['update', rs]);
			}
		}
		len = queue.length;
		if(len){
			batch = ++this.batchCounter;
			for(i = 0; i < len; ++i){
				trans = queue[i];
				data[trans[0]] = trans[1];
			}
			if(this.fireEvent('beforesave', this, data) !== false){
				for(i = 0; i < len; ++i){
					trans = queue[i];
					this.doTransaction(trans[0], trans[1], batch);
				}
				return batch;
			}
		}
		return -1;
	},


	doTransaction : function(action, rs, batch) {
		function transaction(records) {
			try{
				this.execute(action, records, undefined, batch);
			}catch (e){
				this.handleException(e);
			}
		}
		if(this.batch === false){
			for(var i = 0, len = rs.length; i < len; i++){
				transaction.call(this, rs[i]);
			}
		}else{
			transaction.call(this, rs);
		}
	},


	addToBatch : function(batch){
		var b = this.batches,
		key = this.batchKey + batch,
		o = b[key];

		if(!o){
			b[key] = o = {
				id: batch,
				count: 0,
				data: {}
			};
		}
		++o.count;
	},

	removeFromBatch : function(batch, action, data){
		var b = this.batches,
		key = this.batchKey + batch,
		o = b[key],
		arr;


		if(o){
			arr = o.data[action] || [];
			o.data[action] = arr.concat(data);
			if(o.count === 1){
				data = o.data;
				delete b[key];
				this.fireEvent('save', this, batch, data);
			}else{
				--o.count;
			}
		}
	},



	createCallback : function(action, rs, batch) {
		var actions = Ext.data.Api.actions;
		return (action == 'read') ? this.loadRecords : function(data, response, success) {

			this['on' + Ext.util.Format.capitalize(action) + 'Records'](success, rs, [].concat(data));

			if (success === true) {
				this.fireEvent('write', this, action, data, response, rs);
			}
			this.removeFromBatch(batch, action, data);
		};
	},




	clearModified : function(rs) {
		if (Ext.isArray(rs)) {
			for (var n=rs.length-1;n>=0;n--) {
				this.modified.splice(this.modified.indexOf(rs[n]), 1);
			}
		} else {
			this.modified.splice(this.modified.indexOf(rs), 1);
		}
	},


	reMap : function(record) {
		if (Ext.isArray(record)) {
			for (var i = 0, len = record.length; i < len; i++) {
				this.reMap(record[i]);
			}
		} else {
			delete this.data.map[record._phid];
			this.data.map[record.id] = record;
			var index = this.data.keys.indexOf(record._phid);
			this.data.keys.splice(index, 1, record.id);
			delete record._phid;
		}
	},


	onCreateRecords : function(success, rs, data) {
		if (success === true) {
			try {
				this.reader.realize(rs, data);
				this.reMap(rs);
			}
			catch (e) {
				this.handleException(e);
				if (Ext.isArray(rs)) {

					this.onCreateRecords(success, rs, data);
				}
			}
		}
	},


	onUpdateRecords : function(success, rs, data) {
		if (success === true) {
			try {
				this.reader.update(rs, data);
			} catch (e) {
				this.handleException(e);
				if (Ext.isArray(rs)) {

					this.onUpdateRecords(success, rs, data);
				}
			}
		}
	},


	onDestroyRecords : function(success, rs, data) {

		rs = (rs instanceof Ext.data.Record) ? [rs] : [].concat(rs);
		for (var i=0,len=rs.length;i<len;i++) {
			this.removed.splice(this.removed.indexOf(rs[i]), 1);
		}
		if (success === false) {


			for (i=rs.length-1;i>=0;i--) {
				this.insert(rs[i].lastIndex, rs[i]);
			}
		}
	},


	handleException : function(e) {

		Ext.handleError(e);
	},


	reload : function(options){
		this.load(Ext.applyIf(options||{}, this.lastOptions));
	},



	loadRecords : function(o, options, success){
		var i, len;

		if (this.isDestroyed === true) {
			return;
		}
		if(!o || success === false){
			if(success !== false){
				this.fireEvent('load', this, [], options);
			}
			if(options.callback){
				options.callback.call(options.scope || this, [], options, false, o);
			}
			return;
		}
		var r = o.records, t = o.totalRecords || r.length;
		if(!options || options.add !== true){
			if(this.pruneModifiedRecords){
				this.modified = [];
			}
			for(i = 0, len = r.length; i < len; i++){
				r[i].join(this);
			}
			if(this.snapshot){
				this.data = this.snapshot;
				delete this.snapshot;
			}
			this.clearData();
			this.data.addAll(r);
			this.totalLength = t;
			this.applySort();
			this.fireEvent('datachanged', this);
		}else{
			var toAdd = [],
			rec,
			cnt = 0;
			for(i = 0, len = r.length; i < len; ++i){
				rec = r[i];
				if(this.indexOfId(rec.id) > -1){
					this.doUpdate(rec);
				}else{
					toAdd.push(rec);
					++cnt;
				}
			}
			this.totalLength = Math.max(t, this.data.length + cnt);
			this.add(toAdd);
		}
		this.fireEvent('load', this, r, options);
		if(options.callback){
			options.callback.call(options.scope || this, r, options, true);
		}
	},


	loadData : function(o, append){
		var r = this.reader.readRecords(o);
		this.loadRecords(r, {
			add: append
		}, true);
	},


	getCount : function(){
		return this.data.length || 0;
	},


	getTotalCount : function(){
		return this.totalLength || 0;
	},


	getSortState : function(){
		return this.sortInfo;
	},


	applySort : function(){
		if ((this.sortInfo || this.multiSortInfo) && !this.remoteSort) {
			this.sortData();
		}
	},


	sortData : function() {
		var sortInfo  = this.hasMultiSort ? this.multiSortInfo : this.sortInfo,
		direction = sortInfo.direction || "ASC",
		sorters   = sortInfo.sorters,
		sortFns   = [];


		if (!this.hasMultiSort) {
			sorters = [{
				direction: direction,
				field: sortInfo.field
				}];
		}


		for (var i=0, j = sorters.length; i < j; i++) {
			sortFns.push(this.createSortFunction(sorters[i].field, sorters[i].direction));
		}

		if (sortFns.length == 0) {
			return;
		}



		var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1;


		var fn = function(r1, r2) {
			var result = sortFns[0].call(this, r1, r2);


			if (sortFns.length > 1) {
				for (var i=1, j = sortFns.length; i < j; i++) {
					result = result || sortFns[i].call(this, r1, r2);
				}
			}

			return directionModifier * result;
		};


		this.data.sort(direction, fn);
		if (this.snapshot && this.snapshot != this.data) {
			this.snapshot.sort(direction, fn);
		}
	},


	createSortFunction: function(field, direction) {
		direction = direction || "ASC";
		var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1;

		var sortType = this.fields.get(field).sortType;



		return function(r1, r2) {
			var v1 = sortType(r1.data[field]),
			v2 = sortType(r2.data[field]);

			return directionModifier * (v1 > v2 ? 1 : (v1 < v2 ? -1 : 0));
		};
	},


	setDefaultSort : function(field, dir) {
		dir = dir ? dir.toUpperCase() : 'ASC';
		this.sortInfo = {
			field: field,
			direction: dir
		};
		this.sortToggle[field] = dir;
	},


	sort : function(fieldName, dir) {
		if (Ext.isArray(arguments[0])) {
			return this.multiSort.call(this, fieldName, dir);
		} else {
			return this.singleSort(fieldName, dir);
		}
	},


	singleSort: function(fieldName, dir) {
		var field = this.fields.get(fieldName);
		if (!field) {
			return false;
		}

		var name       = field.name,
		sortInfo   = this.sortInfo || null,
		sortToggle = this.sortToggle ? this.sortToggle[name] : null;

		if (!dir) {
			if (sortInfo && sortInfo.field == name) {
				dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC');
			} else {
				dir = field.sortDir;
			}
		}

		this.sortToggle[name] = dir;
		this.sortInfo = {
			field: name,
			direction: dir
		};
		this.hasMultiSort = false;

		if (this.remoteSort) {
			if (!this.load(this.lastOptions)) {
				if (sortToggle) {
					this.sortToggle[name] = sortToggle;
				}
				if (sortInfo) {
					this.sortInfo = sortInfo;
				}
			}
		} else {
			this.applySort();
			this.fireEvent('datachanged', this);
		}
		return true;
	},


	multiSort: function(sorters, direction) {
		this.hasMultiSort = true;
		direction = direction || "ASC";


		if (this.multiSortInfo && direction == this.multiSortInfo.direction) {
			direction = direction.toggle("ASC", "DESC");
		}


		this.multiSortInfo = {
			sorters  : sorters,
			direction: direction
		};

		if (this.remoteSort) {
			this.singleSort(sorters[0].field, sorters[0].direction);

		} else {
			this.applySort();
			this.fireEvent('datachanged', this);
		}
	},


	each : function(fn, scope){
		this.data.each(fn, scope);
	},


	getModifiedRecords : function(){
		return this.modified;
	},


	sum : function(property, start, end){
		var rs = this.data.items, v = 0;
		start = start || 0;
		end = (end || end === 0) ? end : rs.length-1;

		for(var i = start; i <= end; i++){
			v += (rs[i].data[property] || 0);
		}
		return v;
	},


	createFilterFn : function(property, value, anyMatch, caseSensitive, exactMatch){
		if(Ext.isEmpty(value, false)){
			return false;
		}
		value = this.data.createValueMatcher(value, anyMatch, caseSensitive, exactMatch);
		return function(r) {
			return value.test(r.data[property]);
		};
	},


	createMultipleFilterFn: function(filters) {
		return function(record) {
			var isMatch = true;

			for (var i=0, j = filters.length; i < j; i++) {
				var filter = filters[i],
				fn     = filter.fn,
				scope  = filter.scope;

				isMatch = isMatch && fn.call(scope, record);
			}

			return isMatch;
		};
	},


	filter : function(property, value, anyMatch, caseSensitive, exactMatch){
		var fn;

		if (Ext.isObject(property)) {
			property = [property];
		}

		if (Ext.isArray(property)) {
			var filters = [];


			for (var i=0, j = property.length; i < j; i++) {
				var filter = property[i],
				func   = filter.fn,
				scope  = filter.scope || this;


				if (!Ext.isFunction(func)) {
					func = this.createFilterFn(filter.property, filter.value, filter.anyMatch, filter.caseSensitive, filter.exactMatch);
				}

				filters.push({
					fn: func,
					scope: scope
				});
			}

			fn = this.createMultipleFilterFn(filters);
		} else {

			fn = this.createFilterFn(property, value, anyMatch, caseSensitive, exactMatch);
		}

		return fn ? this.filterBy(fn) : this.clearFilter();
	},


	filterBy : function(fn, scope){
		this.snapshot = this.snapshot || this.data;
		this.data = this.queryBy(fn, scope || this);
		this.fireEvent('datachanged', this);
	},


	clearFilter : function(suppressEvent){
		if(this.isFiltered()){
			this.data = this.snapshot;
			delete this.snapshot;
			if(suppressEvent !== true){
				this.fireEvent('datachanged', this);
			}
		}
	},


	isFiltered : function(){
		return !!this.snapshot && this.snapshot != this.data;
	},


	query : function(property, value, anyMatch, caseSensitive){
		var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
		return fn ? this.queryBy(fn) : this.data.clone();
	},


	queryBy : function(fn, scope){
		var data = this.snapshot || this.data;
		return data.filterBy(fn, scope||this);
	},


	find : function(property, value, start, anyMatch, caseSensitive){
		var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
		return fn ? this.data.findIndexBy(fn, null, start) : -1;
	},


	findExact: function(property, value, start){
		return this.data.findIndexBy(function(rec){
			return rec.get(property) === value;
		}, this, start);
	},


	findBy : function(fn, scope, start){
		return this.data.findIndexBy(fn, scope, start);
	},


	collect : function(dataIndex, allowNull, bypassFilter){
		var d = (bypassFilter === true && this.snapshot) ?
		this.snapshot.items : this.data.items;
		var v, sv, r = [], l = {};
		for(var i = 0, len = d.length; i < len; i++){
			v = d[i].data[dataIndex];
			sv = String(v);
			if((allowNull || !Ext.isEmpty(v)) && !l[sv]){
				l[sv] = true;
				r[r.length] = v;
			}
		}
		return r;
	},


	afterEdit : function(record){
		if(this.modified.indexOf(record) == -1){
			this.modified.push(record);
		}
		this.fireEvent('update', this, record, Ext.data.Record.EDIT);
	},


	afterReject : function(record){
		this.modified.remove(record);
		this.fireEvent('update', this, record, Ext.data.Record.REJECT);
	},


	afterCommit : function(record){
		this.modified.remove(record);
		this.fireEvent('update', this, record, Ext.data.Record.COMMIT);
	},


	commitChanges : function(){
		var modified = this.modified.slice(0),
		length   = modified.length,
		i;

		for (i = 0; i < length; i++){
			modified[i].commit();
		}

		this.modified = [];
		this.removed  = [];
	},


	rejectChanges : function() {
		var modified = this.modified.slice(0),
		removed  = this.removed.slice(0).reverse(),
		mLength  = modified.length,
		rLength  = removed.length,
		i;

		for (i = 0; i < mLength; i++) {
			modified[i].reject();
		}

		for (i = 0; i < rLength; i++) {
			this.insert(removed[i].lastIndex || 0, removed[i]);
			removed[i].reject();
		}

		this.modified = [];
		this.removed  = [];
	},


	onMetaChange : function(meta){
		this.recordType = this.reader.recordType;
		this.fields = this.recordType.prototype.fields;
		delete this.snapshot;
		if(this.reader.meta.sortInfo){
			this.sortInfo = this.reader.meta.sortInfo;
		}else if(this.sortInfo  && !this.fields.get(this.sortInfo.field)){
			delete this.sortInfo;
		}
		if(this.writer){
			this.writer.meta = this.reader.meta;
		}
		this.modified = [];
		this.fireEvent('metachange', this, this.reader.meta);
	},


	findInsertIndex : function(record){
		this.suspendEvents();
		var data = this.data.clone();
		this.data.add(record);
		this.applySort();
		var index = this.data.indexOf(record);
		this.data = data;
		this.resumeEvents();
		return index;
	},


	setBaseParam : function (name, value){
		this.baseParams = this.baseParams || {};
		this.baseParams[name] = value;
	}
});

Ext.reg('store', Ext.data.Store);


Ext.data.Store.Error = Ext.extend(Ext.Error, {
	name: 'Ext.data.Store'
});
Ext.apply(Ext.data.Store.Error.prototype, {
	lang: {
		'writer-undefined' : 'Attempted to execute a write-action without a DataWriter installed.'
	}
});

Ext.data.Field = Ext.extend(Object, {

	constructor : function(config){
		if(Ext.isString(config)){
			config = {
				name: config
			};
		}
		Ext.apply(this, config);

		var types = Ext.data.Types,
		st = this.sortType,
		t;

		if(this.type){
			if(Ext.isString(this.type)){
				this.type = Ext.data.Types[this.type.toUpperCase()] || types.AUTO;
			}
		}else{
			this.type = types.AUTO;
		}


		if(Ext.isString(st)){
			this.sortType = Ext.data.SortTypes[st];
		}else if(Ext.isEmpty(st)){
			this.sortType = this.type.sortType;
		}

		if(!this.convert){
			this.convert = this.type.convert;
		}
	},





	dateFormat: null,


	useNull: false,


	defaultValue: "",

	mapping: null,

	sortType : null,

	sortDir : "ASC",

	allowBlank : true
});

Ext.data.DataReader = function(meta, recordType){

	this.meta = meta;

	this.recordType = Ext.isArray(recordType) ?
	Ext.data.Record.create(recordType) : recordType;


	if (this.recordType){
		this.buildExtractors();
	}
};

Ext.data.DataReader.prototype = {


	getTotal: Ext.emptyFn,

	getRoot: Ext.emptyFn,

	getMessage: Ext.emptyFn,

	getSuccess: Ext.emptyFn,

	getId: Ext.emptyFn,

	buildExtractors : Ext.emptyFn,

	extractValues : Ext.emptyFn,


	realize: function(rs, data){
		if (Ext.isArray(rs)) {
			for (var i = rs.length - 1; i >= 0; i--) {

				if (Ext.isArray(data)) {
					this.realize(rs.splice(i,1).shift(), data.splice(i,1).shift());
				}
				else {


					this.realize(rs.splice(i,1).shift(), data);
				}
			}
		}
		else {

			if (Ext.isArray(data) && data.length == 1) {
				data = data.shift();
			}
			if (!this.isData(data)) {


				throw new Ext.data.DataReader.Error('realize', rs);
			}
			rs.phantom = false;
			rs._phid = rs.id;
			rs.id = this.getId(data);
			rs.data = data;

			rs.commit();
		}
	},


	update : function(rs, data) {
		if (Ext.isArray(rs)) {
			for (var i=rs.length-1; i >= 0; i--) {
				if (Ext.isArray(data)) {
					this.update(rs.splice(i,1).shift(), data.splice(i,1).shift());
				}
				else {


					this.update(rs.splice(i,1).shift(), data);
				}
			}
		}
		else {

			if (Ext.isArray(data) && data.length == 1) {
				data = data.shift();
			}
			if (this.isData(data)) {
				rs.data = Ext.apply(rs.data, data);
			}
			rs.commit();
		}
	},


	extractData : function(root, returnRecords) {

		var rawName = (this instanceof Ext.data.JsonReader) ? 'json' : 'node';

		var rs = [];



		if (this.isData(root) && !(this instanceof Ext.data.XmlReader)) {
			root = [root];
		}
		var f       = this.recordType.prototype.fields,
		fi      = f.items,
		fl      = f.length,
		rs      = [];
		if (returnRecords === true) {
			var Record = this.recordType;
			for (var i = 0; i < root.length; i++) {
				var n = root[i];
				var record = new Record(this.extractValues(n, fi, fl), this.getId(n));
				record[rawName] = n;
				rs.push(record);
			}
		}
		else {
			for (var i = 0; i < root.length; i++) {
				var data = this.extractValues(root[i], fi, fl);
				data[this.meta.idProperty] = this.getId(root[i]);
				rs.push(data);
			}
		}
		return rs;
	},


	isData : function(data) {
		return (data && Ext.isObject(data) && !Ext.isEmpty(this.getId(data))) ? true : false;
	},


	onMetaChange : function(meta){
		delete this.ef;
		this.meta = meta;
		this.recordType = Ext.data.Record.create(meta.fields);
		this.buildExtractors();
	}
};


Ext.data.DataReader.Error = Ext.extend(Ext.Error, {
	constructor : function(message, arg) {
		this.arg = arg;
		Ext.Error.call(this, message);
	},
	name: 'Ext.data.DataReader'
});
Ext.apply(Ext.data.DataReader.Error.prototype, {
	lang : {
		'update': "#update received invalid data from server.  Please see docs for DataReader#update and review your DataReader configuration.",
		'realize': "#realize was called with invalid remote-data.  Please see the docs for DataReader#realize and review your DataReader configuration.",
		'invalid-response': "#readResponse received an invalid response from the server."
	}
});

Ext.data.DataWriter = function(config){
	Ext.apply(this, config);
};
Ext.data.DataWriter.prototype = {


	writeAllFields : false,

	listful : false,


	apply : function(params, baseParams, action, rs) {
		var data    = [],
		renderer    = action + 'Record';

		if (Ext.isArray(rs)) {
			Ext.each(rs, function(rec){
				data.push(this[renderer](rec));
			}, this);
		}
		else if (rs instanceof Ext.data.Record) {
			data = this[renderer](rs);
		}
		this.render(params, baseParams, data);
	},


	render : Ext.emptyFn,


	updateRecord : Ext.emptyFn,


	createRecord : Ext.emptyFn,


	destroyRecord : Ext.emptyFn,


	toHash : function(rec, config) {
		var map = rec.fields.map,
		data = {},
		raw = (this.writeAllFields === false && rec.phantom === false) ? rec.getChanges() : rec.data,
		m;
		Ext.iterate(raw, function(prop, value){
			if((m = map[prop])){
				data[m.mapping ? m.mapping : m.name] = value;
			}
		});



		if (rec.phantom) {
			if (rec.fields.containsKey(this.meta.idProperty) && Ext.isEmpty(rec.data[this.meta.idProperty])) {
				delete data[this.meta.idProperty];
			}
		} else {
			data[this.meta.idProperty] = rec.id;
		}
		return data;
	},


	toArray : function(data) {
		var fields = [];
		Ext.iterate(data, function(k, v) {
			fields.push({
				name: k,
				value: v
			});
		},this);
		return fields;
	}
};
Ext.data.DataProxy = function(conn){


	conn = conn || {};





	this.api     = conn.api;
	this.url     = conn.url;
	this.restful = conn.restful;
	this.listeners = conn.listeners;


	this.prettyUrls = conn.prettyUrls;



	this.addEvents(

		'exception',

		'beforeload',

		'load',

		'loadexception',

		'beforewrite',

		'write'
		);
	Ext.data.DataProxy.superclass.constructor.call(this);


	try {
		Ext.data.Api.prepare(this);
	} catch (e) {
		if (e instanceof Ext.data.Api.Error) {
			e.toConsole();
		}
	}

	Ext.data.DataProxy.relayEvents(this, ['beforewrite', 'write', 'exception']);
};

Ext.extend(Ext.data.DataProxy, Ext.util.Observable, {

	restful: false,


	setApi : function() {
		if (arguments.length == 1) {
			var valid = Ext.data.Api.isValid(arguments[0]);
			if (valid === true) {
				this.api = arguments[0];
			}
			else {
				throw new Ext.data.Api.Error('invalid', valid);
			}
		}
		else if (arguments.length == 2) {
			if (!Ext.data.Api.isAction(arguments[0])) {
				throw new Ext.data.Api.Error('invalid', arguments[0]);
			}
			this.api[arguments[0]] = arguments[1];
		}
		Ext.data.Api.prepare(this);
	},


	isApiAction : function(action) {
		return (this.api[action]) ? true : false;
	},


	request : function(action, rs, params, reader, callback, scope, options) {
		if (!this.api[action] && !this.load) {
			throw new Ext.data.DataProxy.Error('action-undefined', action);
		}
		params = params || {};
		if ((action === Ext.data.Api.actions.read) ? this.fireEvent("beforeload", this, params) : this.fireEvent("beforewrite", this, action, rs, params) !== false) {
			this.doRequest.apply(this, arguments);
		}
		else {
			callback.call(scope || this, null, options, false);
		}
	},



	load : null,


	doRequest : function(action, rs, params, reader, callback, scope, options) {



		this.load(params, reader, callback, scope, options);
	},


	onRead : Ext.emptyFn,

	onWrite : Ext.emptyFn,

	buildUrl : function(action, record) {
		record = record || null;




		var url = (this.conn && this.conn.url) ? this.conn.url : (this.api[action]) ? this.api[action].url : this.url;
		if (!url) {
			throw new Ext.data.Api.Error('invalid-url', action);
		}







		var provides = null;
		var m = url.match(/(.*)(\.json|\.xml|\.html)$/);
		if (m) {
			provides = m[2];
			url      = m[1];
		}

		if ((this.restful === true || this.prettyUrls === true) && record instanceof Ext.data.Record && !record.phantom) {
			url += '/' + record.id;
		}
		return (provides === null) ? url : url + provides;
	},


	destroy: function(){
		this.purgeListeners();
	}
});



Ext.apply(Ext.data.DataProxy, Ext.util.Observable.prototype);
Ext.util.Observable.call(Ext.data.DataProxy);


Ext.data.DataProxy.Error = Ext.extend(Ext.Error, {
	constructor : function(message, arg) {
		this.arg = arg;
		Ext.Error.call(this, message);
	},
	name: 'Ext.data.DataProxy'
});
Ext.apply(Ext.data.DataProxy.Error.prototype, {
	lang: {
		'action-undefined': "DataProxy attempted to execute an API-action but found an undefined url / function.  Please review your Proxy url/api-configuration.",
		'api-invalid': 'Recieved an invalid API-configuration.  Please ensure your proxy API-configuration contains only the actions from Ext.data.Api.actions.'
	}
});



Ext.data.Request = function(params) {
	Ext.apply(this, params);
};
Ext.data.Request.prototype = {

	action : undefined,

	rs : undefined,

	params: undefined,

	callback : Ext.emptyFn,

	scope : undefined,

	reader : undefined
};

Ext.data.Response = function(params) {
	Ext.apply(this, params);
};
Ext.data.Response.prototype = {

	action: undefined,

	success : undefined,

	message : undefined,

	data: undefined,

	raw: undefined,

	records: undefined
};

Ext.data.ScriptTagProxy = function(config){
	Ext.apply(this, config);

	Ext.data.ScriptTagProxy.superclass.constructor.call(this, config);

	this.head = document.getElementsByTagName("head")[0];


};

Ext.data.ScriptTagProxy.TRANS_ID = 1000;

Ext.extend(Ext.data.ScriptTagProxy, Ext.data.DataProxy, {


	timeout : 30000,

	callbackParam : "callback",

	nocache : true,


	doRequest : function(action, rs, params, reader, callback, scope, arg) {
		var p = Ext.urlEncode(Ext.apply(params, this.extraParams));

		var url = this.buildUrl(action, rs);
		if (!url) {
			throw new Ext.data.Api.Error('invalid-url', url);
		}
		url = Ext.urlAppend(url, p);

		if(this.nocache){
			url = Ext.urlAppend(url, '_dc=' + (new Date().getTime()));
		}
		var transId = ++Ext.data.ScriptTagProxy.TRANS_ID;
		var trans = {
			id : transId,
			action: action,
			cb : "stcCallback"+transId,
			scriptId : "stcScript"+transId,
			params : params,
			arg : arg,
			url : url,
			callback : callback,
			scope : scope,
			reader : reader
		};
		window[trans.cb] = this.createCallback(action, rs, trans);
		url += String.format("&{0}={1}", this.callbackParam, trans.cb);
		if(this.autoAbort !== false){
			this.abort();
		}

		trans.timeoutId = this.handleFailure.defer(this.timeout, this, [trans]);

		var script = document.createElement("script");
		script.setAttribute("src", url);
		script.setAttribute("type", "text/javascript");
		script.setAttribute("id", trans.scriptId);
		this.head.appendChild(script);

		this.trans = trans;
	},


	createCallback : function(action, rs, trans) {
		var self = this;
		return function(res) {
			self.trans = false;
			self.destroyTrans(trans, true);
			if (action === Ext.data.Api.actions.read) {
				self.onRead.call(self, action, trans, res);
			} else {
				self.onWrite.call(self, action, trans, res, rs);
			}
		};
	},

	onRead : function(action, trans, res) {
		var result;
		try {
			result = trans.reader.readRecords(res);
		}catch(e){

			this.fireEvent("loadexception", this, trans, res, e);

			this.fireEvent('exception', this, 'response', action, trans, res, e);
			trans.callback.call(trans.scope||window, null, trans.arg, false);
			return;
		}
		if (result.success === false) {

			this.fireEvent('loadexception', this, trans, res);

			this.fireEvent('exception', this, 'remote', action, trans, res, null);
		} else {
			this.fireEvent("load", this, res, trans.arg);
		}
		trans.callback.call(trans.scope||window, result, trans.arg, result.success);
	},

	onWrite : function(action, trans, response, rs) {
		var reader = trans.reader;
		try {

			var res = reader.readResponse(action, response);
		} catch (e) {
			this.fireEvent('exception', this, 'response', action, trans, res, e);
			trans.callback.call(trans.scope||window, null, res, false);
			return;
		}
		if(!res.success === true){
			this.fireEvent('exception', this, 'remote', action, trans, res, rs);
			trans.callback.call(trans.scope||window, null, res, false);
			return;
		}
		this.fireEvent("write", this, action, res.data, res, rs, trans.arg );
		trans.callback.call(trans.scope||window, res.data, res, true);
	},


	isLoading : function(){
		return this.trans ? true : false;
	},


	abort : function(){
		if(this.isLoading()){
			this.destroyTrans(this.trans);
		}
	},


	destroyTrans : function(trans, isLoaded){
		this.head.removeChild(document.getElementById(trans.scriptId));
		clearTimeout(trans.timeoutId);
		if(isLoaded){
			window[trans.cb] = undefined;
			try{
				delete window[trans.cb];
			}catch(e){}
		}else{

			window[trans.cb] = function(){
				window[trans.cb] = undefined;
				try{
					delete window[trans.cb];
				}catch(e){}
			};
		}
	},


	handleFailure : function(trans){
		this.trans = false;
		this.destroyTrans(trans, false);
		if (trans.action === Ext.data.Api.actions.read) {

			this.fireEvent("loadexception", this, null, trans.arg);
		}

		this.fireEvent('exception', this, 'response', trans.action, {
			response: null,
			options: trans.arg
		});
		trans.callback.call(trans.scope||window, null, trans.arg, false);
	},


	destroy: function(){
		this.abort();
		Ext.data.ScriptTagProxy.superclass.destroy.call(this);
	}
});
Ext.data.HttpProxy = function(conn){
	Ext.data.HttpProxy.superclass.constructor.call(this, conn);


	this.conn = conn;





	this.conn.url = null;

	this.useAjax = !conn || !conn.events;


	var actions = Ext.data.Api.actions;
	this.activeRequest = {};
	for (var verb in actions) {
		this.activeRequest[actions[verb]] = undefined;
	}
};

Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, {

	getConnection : function() {
		return this.useAjax ? Ext.Ajax : this.conn;
	},


	setUrl : function(url, makePermanent) {
		this.conn.url = url;
		if (makePermanent === true) {
			this.url = url;
			this.api = null;
			Ext.data.Api.prepare(this);
		}
	},


	doRequest : function(action, rs, params, reader, cb, scope, arg) {
		var  o = {
			method: (this.api[action]) ? this.api[action]['method'] : undefined,
			request: {
				callback : cb,
				scope : scope,
				arg : arg
			},
			reader: reader,
			callback : this.createCallback(action, rs),
			scope: this
		};



		if (params.jsonData) {
			o.jsonData = params.jsonData;
		} else if (params.xmlData) {
			o.xmlData = params.xmlData;
		} else {
			o.params = params || {};
		}



		this.conn.url = this.buildUrl(action, rs);

		if(this.useAjax){

			Ext.applyIf(o, this.conn);


			if (this.activeRequest[action]) {





			}
			this.activeRequest[action] = Ext.Ajax.request(o);
		}else{
			this.conn.request(o);
		}

		this.conn.url = null;
	},


	createCallback : function(action, rs) {
		return function(o, success, response) {
			this.activeRequest[action] = undefined;
			if (!success) {
				if (action === Ext.data.Api.actions.read) {


					this.fireEvent('loadexception', this, o, response);
				}
				this.fireEvent('exception', this, 'response', action, o, response);
				o.request.callback.call(o.request.scope, null, o.request.arg, false);
				return;
			}
			if (action === Ext.data.Api.actions.read) {
				this.onRead(action, o, response);
			} else {
				this.onWrite(action, o, response, rs);
			}
		};
	},


	onRead : function(action, o, response) {
		var result;
		try {
			result = o.reader.read(response);
		}catch(e){


			this.fireEvent('loadexception', this, o, response, e);

			this.fireEvent('exception', this, 'response', action, o, response, e);
			o.request.callback.call(o.request.scope, null, o.request.arg, false);
			return;
		}
		if (result.success === false) {


			this.fireEvent('loadexception', this, o, response);


			var res = o.reader.readResponse(action, response);
			this.fireEvent('exception', this, 'remote', action, o, res, null);
		}
		else {
			this.fireEvent('load', this, o, o.request.arg);
		}



		o.request.callback.call(o.request.scope, result, o.request.arg, result.success);
	},

	onWrite : function(action, o, response, rs) {
		var reader = o.reader;
		var res;
		try {
			res = reader.readResponse(action, response);
		} catch (e) {
			this.fireEvent('exception', this, 'response', action, o, response, e);
			o.request.callback.call(o.request.scope, null, o.request.arg, false);
			return;
		}
		if (res.success === true) {
			this.fireEvent('write', this, action, res.data, res, rs, o.request.arg);
		} else {
			this.fireEvent('exception', this, 'remote', action, o, res, rs);
		}



		o.request.callback.call(o.request.scope, res.data, res, res.success);
	},


	destroy: function(){
		if(!this.useAjax){
			this.conn.abort();
		}else if(this.activeRequest){
			var actions = Ext.data.Api.actions;
			for (var verb in actions) {
				if(this.activeRequest[actions[verb]]){
					Ext.Ajax.abort(this.activeRequest[actions[verb]]);
				}
			}
		}
		Ext.data.HttpProxy.superclass.destroy.call(this);
	}
});
Ext.data.MemoryProxy = function(data){

	var api = {};
	api[Ext.data.Api.actions.read] = true;
	Ext.data.MemoryProxy.superclass.constructor.call(this, {
		api: api
	});
	this.data = data;
};

Ext.extend(Ext.data.MemoryProxy, Ext.data.DataProxy, {



	doRequest : function(action, rs, params, reader, callback, scope, arg) {

		params = params || {};
		var result;
		try {
			result = reader.readRecords(this.data);
		}catch(e){

			this.fireEvent("loadexception", this, null, arg, e);

			this.fireEvent('exception', this, 'response', action, arg, null, e);
			callback.call(scope, null, arg, false);
			return;
		}
		callback.call(scope, result, arg, true);
	}
});
Ext.data.Types = new function(){
	var st = Ext.data.SortTypes;
	Ext.apply(this, {

		stripRe: /[\$,%]/g,


		AUTO: {
			convert: function(v){
				return v;
			},
			sortType: st.none,
			type: 'auto'
		},


		STRING: {
			convert: function(v){
				return (v === undefined || v === null) ? '' : String(v);
			},
			sortType: st.asUCString,
			type: 'string'
		},


		INT: {
			convert: function(v){
				return v !== undefined && v !== null && v !== '' ?
				parseInt(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0);
			},
			sortType: st.none,
			type: 'int'
		},


		FLOAT: {
			convert: function(v){
				return v !== undefined && v !== null && v !== '' ?
				parseFloat(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0);
			},
			sortType: st.none,
			type: 'float'
		},


		BOOL: {
			convert: function(v){
				return v === true || v === 'true' || v == 1;
			},
			sortType: st.none,
			type: 'bool'
		},


		DATE: {
			convert: function(v){
				var df = this.dateFormat;
				if(!v){
					return null;
				}
				if(Ext.isDate(v)){
					return v;
				}
				if(df){
					if(df == 'timestamp'){
						return new Date(v*1000);
					}
					if(df == 'time'){
						return new Date(parseInt(v, 10));
					}
					return Date.parseDate(v, df);
				}
				var parsed = Date.parse(v);
				return parsed ? new Date(parsed) : null;
			},
			sortType: st.asDate,
			type: 'date'
		}
	});

	Ext.apply(this, {

		BOOLEAN: this.BOOL,

		INTEGER: this.INT,

		NUMBER: this.FLOAT
	});
};
Ext.data.JsonWriter = Ext.extend(Ext.data.DataWriter, {

	encode : true,

	encodeDelete: false,

	constructor : function(config){
		Ext.data.JsonWriter.superclass.constructor.call(this, config);
	},


	render : function(params, baseParams, data) {
		if (this.encode === true) {

			Ext.apply(params, baseParams);
			params[this.meta.root] = Ext.encode(data);
		} else {

			var jdata = Ext.apply({}, baseParams);
			jdata[this.meta.root] = data;
			params.jsonData = jdata;
		}
	},

	createRecord : function(rec) {
		return this.toHash(rec);
	},

	updateRecord : function(rec) {
		return this.toHash(rec);

	},

	destroyRecord : function(rec){
		if(this.encodeDelete){
			var data = {};
			data[this.meta.idProperty] = rec.id;
			return data;
		}else{
			return rec.id;
		}
	}
});
Ext.data.JsonReader = function(meta, recordType){
	meta = meta || {};




	Ext.applyIf(meta, {
		idProperty: 'id',
		successProperty: 'success',
		totalProperty: 'total'
	});

	Ext.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);
};
Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {


	read : function(response){
		var json = response.responseText;
		var o = Ext.decode(json);
		if(!o) {
			throw {
				message: 'JsonReader.read: Json object not found'
			};
		}
		return this.readRecords(o);
	},



	readResponse : function(action, response) {
		var o = (response.responseText !== undefined) ? Ext.decode(response.responseText) : response;
		if(!o) {
			throw new Ext.data.JsonReader.Error('response');
		}

		var root = this.getRoot(o);
		if (action === Ext.data.Api.actions.create) {
			var def = Ext.isDefined(root);
			if (def && Ext.isEmpty(root)) {
				throw new Ext.data.JsonReader.Error('root-empty', this.meta.root);
			}
			else if (!def) {
				throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
			}
		}


		var res = new Ext.data.Response({
			action: action,
			success: this.getSuccess(o),
			data: (root) ? this.extractData(root, false) : [],
			message: this.getMessage(o),
			raw: o
		});


		if (Ext.isEmpty(res.success)) {
			throw new Ext.data.JsonReader.Error('successProperty-response', this.meta.successProperty);
		}
		return res;
	},


	readRecords : function(o){

		this.jsonData = o;
		if(o.metaData){
			this.onMetaChange(o.metaData);
		}
		var s = this.meta, Record = this.recordType,
		f = Record.prototype.fields, fi = f.items, fl = f.length, v;

		var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
		if(s.totalProperty){
			v = parseInt(this.getTotal(o), 10);
			if(!isNaN(v)){
				totalRecords = v;
			}
		}
		if(s.successProperty){
			v = this.getSuccess(o);
			if(v === false || v === 'false'){
				success = false;
			}
		}


		return {
			success : success,
			records : this.extractData(root, true),
			totalRecords : totalRecords
		};
	},


	buildExtractors : function() {
		if(this.ef){
			return;
		}
		var s = this.meta, Record = this.recordType,
		f = Record.prototype.fields, fi = f.items, fl = f.length;

		if(s.totalProperty) {
			this.getTotal = this.createAccessor(s.totalProperty);
		}
		if(s.successProperty) {
			this.getSuccess = this.createAccessor(s.successProperty);
		}
		if (s.messageProperty) {
			this.getMessage = this.createAccessor(s.messageProperty);
		}
		this.getRoot = s.root ? this.createAccessor(s.root) : function(p){
			return p;
		};
		if (s.id || s.idProperty) {
			var g = this.createAccessor(s.id || s.idProperty);
			this.getId = function(rec) {
				var r = g(rec);
				return (r === undefined || r === '') ? null : r;
			};
		} else {
			this.getId = function(){
				return null;
			};
		}
		var ef = [];
		for(var i = 0; i < fl; i++){
			f = fi[i];
			var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
			ef.push(this.createAccessor(map));
		}
		this.ef = ef;
	},


	simpleAccess : function(obj, subsc) {
		return obj[subsc];
	},


	createAccessor : function(){
		var re = /[\[\.]/;
		return function(expr) {
			if(Ext.isEmpty(expr)){
				return Ext.emptyFn;
			}
			if(Ext.isFunction(expr)){
				return expr;
			}
			var i = String(expr).search(re);
			if(i >= 0){
				return new Function('obj', 'return obj' + (i > 0 ? '.' : '') + expr);
			}
			return function(obj){
				return obj[expr];
			};

		};
	}(),


	extractValues : function(data, items, len) {
		var f, values = {};
		for(var j = 0; j < len; j++){
			f = items[j];
			var v = this.ef[j](data);
			values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
		}
		return values;
	}
});


Ext.data.JsonReader.Error = Ext.extend(Ext.Error, {
	constructor : function(message, arg) {
		this.arg = arg;
		Ext.Error.call(this, message);
	},
	name : 'Ext.data.JsonReader'
});
Ext.apply(Ext.data.JsonReader.Error.prototype, {
	lang: {
		'response': 'An error occurred while json-decoding your server response',
		'successProperty-response': 'Could not locate your "successProperty" in your server response.  Please review your JsonReader config to ensure the config-property "successProperty" matches the property in your server-response.  See the JsonReader docs.',
		'root-undefined-config': 'Your JsonReader was configured without a "root" property.  Please review your JsonReader config and make sure to define the root property.  See the JsonReader docs.',
		'idProperty-undefined' : 'Your JsonReader was configured without an "idProperty"  Please review your JsonReader configuration and ensure the "idProperty" is set (e.g.: "id").  See the JsonReader docs.',
		'root-empty': 'Data was expected to be returned by the server in the "root" property of the response.  Please review your JsonReader configuration to ensure the "root" property matches that returned in the server-response.  See JsonReader docs.'
	}
});

Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, {




	readRecords : function(o){
		this.arrayData = o;
		var s = this.meta,
		sid = s ? Ext.num(s.idIndex, s.id) : null,
		recordType = this.recordType,
		fields = recordType.prototype.fields,
		records = [],
		success = true,
		v;

		var root = this.getRoot(o);

		for(var i = 0, len = root.length; i < len; i++) {
			var n = root[i],
			values = {},
			id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
			for(var j = 0, jlen = fields.length; j < jlen; j++) {
				var f = fields.items[j],
				k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
				v = n[k] !== undefined ? n[k] : f.defaultValue;
				v = f.convert(v, n);
				values[f.name] = v;
			}
			var record = new recordType(values, id);
			record.json = n;
			records[records.length] = record;
		}

		var totalRecords = records.length;

		if(s.totalProperty) {
			v = parseInt(this.getTotal(o), 10);
			if(!isNaN(v)) {
				totalRecords = v;
			}
		}
		if(s.successProperty){
			v = this.getSuccess(o);
			if(v === false || v === 'false'){
				success = false;
			}
		}

		return {
			success : success,
			records : records,
			totalRecords : totalRecords
		};
	}
});
Ext.data.ArrayStore = Ext.extend(Ext.data.Store, {

	constructor: function(config){
		Ext.data.ArrayStore.superclass.constructor.call(this, Ext.apply(config, {
			reader: new Ext.data.ArrayReader(config)
		}));
	},

	loadData : function(data, append){
		if(this.expandData === true){
			var r = [];
			for(var i = 0, len = data.length; i < len; i++){
				r[r.length] = [data[i]];
			}
			data = r;
		}
		Ext.data.ArrayStore.superclass.loadData.call(this, data, append);
	}
});
Ext.reg('arraystore', Ext.data.ArrayStore);


Ext.data.SimpleStore = Ext.data.ArrayStore;
Ext.reg('simplestore', Ext.data.SimpleStore);
Ext.data.JsonStore = Ext.extend(Ext.data.Store, {

	constructor: function(config){
		Ext.data.JsonStore.superclass.constructor.call(this, Ext.apply(config, {
			reader: new Ext.data.JsonReader(config)
		}));
	}
});
Ext.reg('jsonstore', Ext.data.JsonStore);
Ext.data.XmlWriter = function(params) {
	Ext.data.XmlWriter.superclass.constructor.apply(this, arguments);

	this.tpl = (typeof(this.tpl) === 'string') ? new Ext.XTemplate(this.tpl).compile() : this.tpl.compile();
};
Ext.extend(Ext.data.XmlWriter, Ext.data.DataWriter, {

	documentRoot: 'xrequest',

	forceDocumentRoot: false,

	root: 'records',

	xmlVersion : '1.0',

	xmlEncoding: 'ISO-8859-15',


	tpl: '<tpl for="."><\u003fxml version="{version}" encoding="{encoding}"\u003f><tpl if="documentRoot"><{documentRoot}><tpl for="baseParams"><tpl for="."><{name}>{value}</{name}></tpl></tpl></tpl><tpl if="records.length&gt;1"><{root}></tpl><tpl for="records"><{parent.record}><tpl for="."><{name}>{value}</{name}></tpl></{parent.record}></tpl><tpl if="records.length&gt;1"></{root}></tpl><tpl if="documentRoot"></{documentRoot}></tpl></tpl>',



	render : function(params, baseParams, data) {
		baseParams = this.toArray(baseParams);
		params.xmlData = this.tpl.applyTemplate({
			version: this.xmlVersion,
			encoding: this.xmlEncoding,
			documentRoot: (baseParams.length > 0 || this.forceDocumentRoot === true) ? this.documentRoot : false,
			record: this.meta.record,
			root: this.root,
			baseParams: baseParams,
			records: (Ext.isArray(data[0])) ? data : [data]
		});
	},


	createRecord : function(rec) {
		return this.toArray(this.toHash(rec));
	},


	updateRecord : function(rec) {
		return this.toArray(this.toHash(rec));

	},

	destroyRecord : function(rec) {
		var data = {};
		data[this.meta.idProperty] = rec.id;
		return this.toArray(data);
	}
});

Ext.data.XmlReader = function(meta, recordType){
	meta = meta || {};


	Ext.applyIf(meta, {
		idProperty: meta.idProperty || meta.idPath || meta.id,
		successProperty: meta.successProperty || meta.success
	});

	Ext.data.XmlReader.superclass.constructor.call(this, meta, recordType || meta.fields);
};
Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {

	read : function(response){
		var doc = response.responseXML;
		if(!doc) {
			throw {
				message: "XmlReader.read: XML Document not available"
			};
		}
		return this.readRecords(doc);
	},


	readRecords : function(doc){

		this.xmlData = doc;

		var root    = doc.documentElement || doc,
		q       = Ext.DomQuery,
		totalRecords = 0,
		success = true;

		if(this.meta.totalProperty){
			totalRecords = this.getTotal(root, 0);
		}
		if(this.meta.successProperty){
			success = this.getSuccess(root);
		}

		var records = this.extractData(q.select(this.meta.record, root), true);


		return {
			success : success,
			records : records,
			totalRecords : totalRecords || records.length
		};
	},


	readResponse : function(action, response) {
		var q = Ext.DomQuery,
		doc = response.responseXML,
		root = doc.documentElement || doc;


		var res = new Ext.data.Response({
			action: action,
			success : this.getSuccess(root),
			message: this.getMessage(root),
			data: this.extractData(q.select(this.meta.record, root) || q.select(this.meta.root, root), false),
			raw: doc
		});

		if (Ext.isEmpty(res.success)) {
			throw new Ext.data.DataReader.Error('successProperty-response', this.meta.successProperty);
		}


		if (action === Ext.data.Api.actions.create) {
			var def = Ext.isDefined(res.data);
			if (def && Ext.isEmpty(res.data)) {
				throw new Ext.data.JsonReader.Error('root-empty', this.meta.root);
			}
			else if (!def) {
				throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
			}
		}
		return res;
	},

	getSuccess : function() {
		return true;
	},


	buildExtractors : function() {
		if(this.ef){
			return;
		}
		var s       = this.meta,
		Record  = this.recordType,
		f       = Record.prototype.fields,
		fi      = f.items,
		fl      = f.length;

		if(s.totalProperty) {
			this.getTotal = this.createAccessor(s.totalProperty);
		}
		if(s.successProperty) {
			this.getSuccess = this.createAccessor(s.successProperty);
		}
		if (s.messageProperty) {
			this.getMessage = this.createAccessor(s.messageProperty);
		}
		this.getRoot = function(res) {
			return (!Ext.isEmpty(res[this.meta.record])) ? res[this.meta.record] : res[this.meta.root];
		};
		if (s.idPath || s.idProperty) {
			var g = this.createAccessor(s.idPath || s.idProperty);
			this.getId = function(rec) {
				var id = g(rec) || rec.id;
				return (id === undefined || id === '') ? null : id;
			};
		} else {
			this.getId = function(){
				return null;
			};
		}
		var ef = [];
		for(var i = 0; i < fl; i++){
			f = fi[i];
			var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
			ef.push(this.createAccessor(map));
		}
		this.ef = ef;
	},


	createAccessor : function(){
		var q = Ext.DomQuery;
		return function(key) {
			if (Ext.isFunction(key)) {
				return key;
			}
			switch(key) {
				case this.meta.totalProperty:
					return function(root, def){
						return q.selectNumber(key, root, def);
					};
					break;
				case this.meta.successProperty:
					return function(root, def) {
						var sv = q.selectValue(key, root, true);
						var success = sv !== false && sv !== 'false';
						return success;
					};
					break;
				default:
					return function(root, def) {
						return q.selectValue(key, root, def);
					};
					break;
			}
		};
	}(),


	extractValues : function(data, items, len) {
		var f, values = {};
		for(var j = 0; j < len; j++){
			f = items[j];
			var v = this.ef[j](data);
			values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
		}
		return values;
	}
});
Ext.data.XmlStore = Ext.extend(Ext.data.Store, {

	constructor: function(config){
		Ext.data.XmlStore.superclass.constructor.call(this, Ext.apply(config, {
			reader: new Ext.data.XmlReader(config)
		}));
	}
});
Ext.reg('xmlstore', Ext.data.XmlStore);
Ext.data.GroupingStore = Ext.extend(Ext.data.Store, {


	constructor: function(config) {
		config = config || {};





		this.hasMultiSort  = true;
		this.multiSortInfo = this.multiSortInfo || {
			sorters: []
		};

		var sorters    = this.multiSortInfo.sorters,
		groupField = config.groupField || this.groupField,
		sortInfo   = config.sortInfo || this.sortInfo,
		groupDir   = config.groupDir || this.groupDir;


		if(groupField){
			sorters.push({
				field    : groupField,
				direction: groupDir
			});
		}


		if (sortInfo) {
			sorters.push(sortInfo);
		}

		Ext.data.GroupingStore.superclass.constructor.call(this, config);

		this.addEvents(

			'groupchange'
			);

		this.applyGroupField();
	},



	remoteGroup : false,

	groupOnSort:false,


	groupDir : 'ASC',


	clearGrouping : function(){
		this.groupField = false;

		if(this.remoteGroup){
			if(this.baseParams){
				delete this.baseParams.groupBy;
				delete this.baseParams.groupDir;
			}
			var lo = this.lastOptions;
			if(lo && lo.params){
				delete lo.params.groupBy;
				delete lo.params.groupDir;
			}

			this.reload();
		}else{
			this.sort();
			this.fireEvent('datachanged', this);
		}
	},


	groupBy : function(field, forceRegroup, direction) {
		direction = direction ? (String(direction).toUpperCase() == 'DESC' ? 'DESC' : 'ASC') : this.groupDir;

		if (this.groupField == field && this.groupDir == direction && !forceRegroup) {
			return;
		}



		var sorters = this.multiSortInfo.sorters;
		if (sorters.length > 0 && sorters[0].field == this.groupField) {
			sorters.shift();
		}

		this.groupField = field;
		this.groupDir = direction;
		this.applyGroupField();

		var fireGroupEvent = function() {
			this.fireEvent('groupchange', this, this.getGroupState());
		};

		if (this.groupOnSort) {
			this.sort(field, direction);
			fireGroupEvent.call(this);
			return;
		}

		if (this.remoteGroup) {
			this.on('load', fireGroupEvent, this, {
				single: true
			});
			this.reload();
		} else {
			this.sort(sorters);
			fireGroupEvent.call(this);
		}
	},



	sort : function(fieldName, dir) {
		if (this.remoteSort) {
			return Ext.data.GroupingStore.superclass.sort.call(this, fieldName, dir);
		}

		var sorters = [];


		if (Ext.isArray(arguments[0])) {
			sorters = arguments[0];
		} else if (fieldName == undefined) {


			sorters = this.sortInfo ? [this.sortInfo] : [];
		} else {


			var field = this.fields.get(fieldName);
			if (!field) return false;

			var name       = field.name,
			sortInfo   = this.sortInfo || null,
			sortToggle = this.sortToggle ? this.sortToggle[name] : null;

			if (!dir) {
				if (sortInfo && sortInfo.field == name) {
					dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC');
				} else {
					dir = field.sortDir;
				}
			}

			this.sortToggle[name] = dir;
			this.sortInfo = {
				field: name,
				direction: dir
			};

			sorters = [this.sortInfo];
		}


		if (this.groupField) {
			sorters.unshift({
				direction: this.groupDir,
				field: this.groupField
				});
		}

		return this.multiSort.call(this, sorters, dir);
	},


	applyGroupField: function(){
		if (this.remoteGroup) {
			if(!this.baseParams){
				this.baseParams = {};
			}

			Ext.apply(this.baseParams, {
				groupBy : this.groupField,
				groupDir: this.groupDir
			});

			var lo = this.lastOptions;
			if (lo && lo.params) {
				lo.params.groupDir = this.groupDir;


				delete lo.params.groupBy;
			}
		}
	},


	applyGrouping : function(alwaysFireChange){
		if(this.groupField !== false){
			this.groupBy(this.groupField, true, this.groupDir);
			return true;
		}else{
			if(alwaysFireChange === true){
				this.fireEvent('datachanged', this);
			}
			return false;
		}
	},


	getGroupState : function(){
		return this.groupOnSort && this.groupField !== false ?
		(this.sortInfo ? this.sortInfo.field : undefined) : this.groupField;
	}
});
Ext.reg('groupingstore', Ext.data.GroupingStore);

Ext.data.DirectProxy = function(config){
	Ext.apply(this, config);
	if(typeof this.paramOrder == 'string'){
		this.paramOrder = this.paramOrder.split(/[\s,|]/);
	}
	Ext.data.DirectProxy.superclass.constructor.call(this, config);
};

Ext.extend(Ext.data.DirectProxy, Ext.data.DataProxy, {

	paramOrder: undefined,


	paramsAsHash: true,


	directFn : undefined,


	doRequest : function(action, rs, params, reader, callback, scope, options) {
		var args = [],
		directFn = this.api[action] || this.directFn;

		switch (action) {
			case Ext.data.Api.actions.create:
				args.push(params.jsonData);
				break;
			case Ext.data.Api.actions.read:

				if(directFn.directCfg.method.len > 0){
					if(this.paramOrder){
						for(var i = 0, len = this.paramOrder.length; i < len; i++){
							args.push(params[this.paramOrder[i]]);
						}
					}else if(this.paramsAsHash){
						args.push(params);
					}
				}
				break;
			case Ext.data.Api.actions.update:
				args.push(params.jsonData);
				break;
			case Ext.data.Api.actions.destroy:
				args.push(params.jsonData);
				break;
		}

		var trans = {
			params : params || {},
			request: {
				callback : callback,
				scope : scope,
				arg : options
			},
			reader: reader
		};

		args.push(this.createCallback(action, rs, trans), this);
		directFn.apply(window, args);
	},


	createCallback : function(action, rs, trans) {
		var me = this;
		return function(result, res) {
			if (!res.status) {

				if (action === Ext.data.Api.actions.read) {
					me.fireEvent("loadexception", me, trans, res, null);
				}
				me.fireEvent('exception', me, 'remote', action, trans, res, null);
				trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);
				return;
			}
			if (action === Ext.data.Api.actions.read) {
				me.onRead(action, trans, result, res);
			} else {
				me.onWrite(action, trans, result, res, rs);
			}
		};
	},


	onRead : function(action, trans, result, res) {
		var records;
		try {
			records = trans.reader.readRecords(result);
		}
		catch (ex) {

			this.fireEvent("loadexception", this, trans, res, ex);

			this.fireEvent('exception', this, 'response', action, trans, res, ex);
			trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);
			return;
		}
		this.fireEvent("load", this, res, trans.request.arg);
		trans.request.callback.call(trans.request.scope, records, trans.request.arg, true);
	},

	onWrite : function(action, trans, result, res, rs) {
		var data = trans.reader.extractData(trans.reader.getRoot(result), false);
		var success = trans.reader.getSuccess(result);
		success = (success !== false);
		if (success){
			this.fireEvent("write", this, action, data, res, rs, trans.request.arg);
		}else{
			this.fireEvent('exception', this, 'remote', action, trans, result, rs);
		}
		trans.request.callback.call(trans.request.scope, data, res, success);
	}
});

Ext.data.DirectStore = Ext.extend(Ext.data.Store, {
	constructor : function(config){

		var c = Ext.apply({}, {
			batchTransactions: false
		}, config);
		Ext.data.DirectStore.superclass.constructor.call(this, Ext.apply(c, {
			proxy: Ext.isDefined(c.proxy) ? c.proxy : new Ext.data.DirectProxy(Ext.copyTo({}, c, 'paramOrder,paramsAsHash,directFn,api')),
			reader: (!Ext.isDefined(c.reader) && c.fields) ? new Ext.data.JsonReader(Ext.copyTo({}, c, 'totalProperty,root,idProperty'), c.fields) : c.reader
		}));
	}
});
Ext.reg('directstore', Ext.data.DirectStore);

Ext.Direct = Ext.extend(Ext.util.Observable, {



	exceptions: {
		TRANSPORT: 'xhr',
		PARSE: 'parse',
		LOGIN: 'login',
		SERVER: 'exception'
	},


	constructor: function(){
		this.addEvents(

			'event',

			'exception'
			);
		this.transactions = {};
		this.providers = {};
	},


	addProvider : function(provider){
		var a = arguments;
		if(a.length > 1){
			for(var i = 0, len = a.length; i < len; i++){
				this.addProvider(a[i]);
			}
			return;
		}


		if(!provider.events){
			provider = new Ext.Direct.PROVIDERS[provider.type](provider);
		}
		provider.id = provider.id || Ext.id();
		this.providers[provider.id] = provider;

		provider.on('data', this.onProviderData, this);
		provider.on('exception', this.onProviderException, this);


		if(!provider.isConnected()){
			provider.connect();
		}

		return provider;
	},


	getProvider : function(id){
		return this.providers[id];
	},

	removeProvider : function(id){
		var provider = id.id ? id : this.providers[id];
		provider.un('data', this.onProviderData, this);
		provider.un('exception', this.onProviderException, this);
		delete this.providers[provider.id];
		return provider;
	},

	addTransaction: function(t){
		this.transactions[t.tid] = t;
		return t;
	},

	removeTransaction: function(t){
		delete this.transactions[t.tid || t];
		return t;
	},

	getTransaction: function(tid){
		return this.transactions[tid.tid || tid];
	},

	onProviderData : function(provider, e){
		if(Ext.isArray(e)){
			for(var i = 0, len = e.length; i < len; i++){
				this.onProviderData(provider, e[i]);
			}
			return;
		}
		if(e.name && e.name != 'event' && e.name != 'exception'){
			this.fireEvent(e.name, e);
		}else if(e.type == 'exception'){
			this.fireEvent('exception', e);
		}
		this.fireEvent('event', e, provider);
	},

	createEvent : function(response, extraProps){
		return new Ext.Direct.eventTypes[response.type](Ext.apply(response, extraProps));
	}
});

Ext.Direct = new Ext.Direct();

Ext.Direct.TID = 1;
Ext.Direct.PROVIDERS = {};
Ext.Direct.Transaction = function(config){
	Ext.apply(this, config);
	this.tid = ++Ext.Direct.TID;
	this.retryCount = 0;
};
Ext.Direct.Transaction.prototype = {
	send: function(){
		this.provider.queueTransaction(this);
	},

	retry: function(){
		this.retryCount++;
		this.send();
	},

	getProvider: function(){
		return this.provider;
	}
};

Ext.Direct.Event = function(config){
	Ext.apply(this, config);
};

Ext.Direct.Event.prototype = {
	status: true,
	getData: function(){
		return this.data;
	}
};

Ext.Direct.RemotingEvent = Ext.extend(Ext.Direct.Event, {
	type: 'rpc',
	getTransaction: function(){
		return this.transaction || Ext.Direct.getTransaction(this.tid);
	}
});

Ext.Direct.ExceptionEvent = Ext.extend(Ext.Direct.RemotingEvent, {
	status: false,
	type: 'exception'
});

Ext.Direct.eventTypes = {
	'rpc':  Ext.Direct.RemotingEvent,
	'event':  Ext.Direct.Event,
	'exception':  Ext.Direct.ExceptionEvent
};

Ext.direct.Provider = Ext.extend(Ext.util.Observable, {



	priority: 1,




	constructor : function(config){
		Ext.apply(this, config);
		this.addEvents(

			'connect',

			'disconnect',

			'data',

			'exception'
			);
		Ext.direct.Provider.superclass.constructor.call(this, config);
	},


	isConnected: function(){
		return false;
	},


	connect: Ext.emptyFn,


	disconnect: Ext.emptyFn
});

Ext.direct.JsonProvider = Ext.extend(Ext.direct.Provider, {
	parseResponse: function(xhr){
		if(!Ext.isEmpty(xhr.responseText)){
			if(typeof xhr.responseText == 'object'){
				return xhr.responseText;
			}
			return Ext.decode(xhr.responseText);
		}
		return null;
	},

	getEvents: function(xhr){
		var data = null;
		try{
			data = this.parseResponse(xhr);
		}catch(e){
			var event = new Ext.Direct.ExceptionEvent({
				data: e,
				xhr: xhr,
				code: Ext.Direct.exceptions.PARSE,
				message: 'Error parsing json response: \n\n ' + data
			});
			return [event];
		}
		var events = [];
		if(Ext.isArray(data)){
			for(var i = 0, len = data.length; i < len; i++){
				events.push(Ext.Direct.createEvent(data[i]));
			}
		}else{
			events.push(Ext.Direct.createEvent(data));
		}
		return events;
	}
});
Ext.direct.PollingProvider = Ext.extend(Ext.direct.JsonProvider, {


	priority: 3,


	interval: 3000,






	constructor : function(config){
		Ext.direct.PollingProvider.superclass.constructor.call(this, config);
		this.addEvents(

			'beforepoll',

			'poll'
			);
	},


	isConnected: function(){
		return !!this.pollTask;
	},


	connect: function(){
		if(this.url && !this.pollTask){
			this.pollTask = Ext.TaskMgr.start({
				run: function(){
					if(this.fireEvent('beforepoll', this) !== false){
						if(typeof this.url == 'function'){
							this.url(this.baseParams);
						}else{
							Ext.Ajax.request({
								url: this.url,
								callback: this.onData,
								scope: this,
								params: this.baseParams
							});
						}
					}
				},
				interval: this.interval,
				scope: this
			});
			this.fireEvent('connect', this);
		}else if(!this.url){
			throw 'Error initializing PollingProvider, no url configured.';
		}
	},


	disconnect: function(){
		if(this.pollTask){
			Ext.TaskMgr.stop(this.pollTask);
			delete this.pollTask;
			this.fireEvent('disconnect', this);
		}
	},


	onData: function(opt, success, xhr){
		if(success){
			var events = this.getEvents(xhr);
			for(var i = 0, len = events.length; i < len; i++){
				var e = events[i];
				this.fireEvent('data', this, e);
			}
		}else{
			var e = new Ext.Direct.ExceptionEvent({
				data: e,
				code: Ext.Direct.exceptions.TRANSPORT,
				message: 'Unable to connect to the server.',
				xhr: xhr
			});
			this.fireEvent('data', this, e);
		}
	}
});

Ext.Direct.PROVIDERS['polling'] = Ext.direct.PollingProvider;
Ext.direct.RemotingProvider = Ext.extend(Ext.direct.JsonProvider, {









	enableBuffer: 10,


	maxRetries: 1,


	timeout: undefined,

	constructor : function(config){
		Ext.direct.RemotingProvider.superclass.constructor.call(this, config);
		this.addEvents(

			'beforecall',

			'call'
			);
		this.namespace = (Ext.isString(this.namespace)) ? Ext.ns(this.namespace) : this.namespace || window;
		this.transactions = {};
		this.callBuffer = [];
	},


	initAPI : function(){
		var o = this.actions;
		for(var c in o){
			var cls = this.namespace[c] || (this.namespace[c] = {}),
			ms = o[c];
			for(var i = 0, len = ms.length; i < len; i++){
				var m = ms[i];
				cls[m.name] = this.createMethod(c, m);
			}
		}
	},


	isConnected: function(){
		return !!this.connected;
	},

	connect: function(){
		if(this.url){
			this.initAPI();
			this.connected = true;
			this.fireEvent('connect', this);
		}else if(!this.url){
			throw 'Error initializing RemotingProvider, no url configured.';
		}
	},

	disconnect: function(){
		if(this.connected){
			this.connected = false;
			this.fireEvent('disconnect', this);
		}
	},

	onData: function(opt, success, xhr){
		if(success){
			var events = this.getEvents(xhr);
			for(var i = 0, len = events.length; i < len; i++){
				var e = events[i],
				t = this.getTransaction(e);
				this.fireEvent('data', this, e);
				if(t){
					this.doCallback(t, e, true);
					Ext.Direct.removeTransaction(t);
				}
			}
		}else{
			var ts = [].concat(opt.ts);
			for(var i = 0, len = ts.length; i < len; i++){
				var t = this.getTransaction(ts[i]);
				if(t && t.retryCount < this.maxRetries){
					t.retry();
				}else{
					var e = new Ext.Direct.ExceptionEvent({
						data: e,
						transaction: t,
						code: Ext.Direct.exceptions.TRANSPORT,
						message: 'Unable to connect to the server.',
						xhr: xhr
					});
					this.fireEvent('data', this, e);
					if(t){
						this.doCallback(t, e, false);
						Ext.Direct.removeTransaction(t);
					}
				}
			}
		}
	},

	getCallData: function(t){
		return {
			action: t.action,
			method: t.method,
			data: t.data,
			type: 'rpc',
			tid: t.tid
		};
	},

	doSend : function(data){
		var o = {
			url: this.url,
			callback: this.onData,
			scope: this,
			ts: data,
			timeout: this.timeout
		}, callData;

		if(Ext.isArray(data)){
			callData = [];
			for(var i = 0, len = data.length; i < len; i++){
				callData.push(this.getCallData(data[i]));
			}
		}else{
			callData = this.getCallData(data);
		}

		if(this.enableUrlEncode){
			var params = {};
			params[Ext.isString(this.enableUrlEncode) ? this.enableUrlEncode : 'data'] = Ext.encode(callData);
			o.params = params;
		}else{
			o.jsonData = callData;
		}
		Ext.Ajax.request(o);
	},

	combineAndSend : function(){
		var len = this.callBuffer.length;
		if(len > 0){
			this.doSend(len == 1 ? this.callBuffer[0] : this.callBuffer);
			this.callBuffer = [];
		}
	},

	queueTransaction: function(t){
		if(t.form){
			this.processForm(t);
			return;
		}
		this.callBuffer.push(t);
		if(this.enableBuffer){
			if(!this.callTask){
				this.callTask = new Ext.util.DelayedTask(this.combineAndSend, this);
			}
			this.callTask.delay(Ext.isNumber(this.enableBuffer) ? this.enableBuffer : 10);
		}else{
			this.combineAndSend();
		}
	},

	doCall : function(c, m, args){
		var data = null, hs = args[m.len], scope = args[m.len+1];

		if(m.len !== 0){
			data = args.slice(0, m.len);
		}

		var t = new Ext.Direct.Transaction({
			provider: this,
			args: args,
			action: c,
			method: m.name,
			data: data,
			cb: scope && Ext.isFunction(hs) ? hs.createDelegate(scope) : hs
		});

		if(this.fireEvent('beforecall', this, t, m) !== false){
			Ext.Direct.addTransaction(t);
			this.queueTransaction(t);
			this.fireEvent('call', this, t, m);
		}
	},

	doForm : function(c, m, form, callback, scope){
		var t = new Ext.Direct.Transaction({
			provider: this,
			action: c,
			method: m.name,
			args:[form, callback, scope],
			cb: scope && Ext.isFunction(callback) ? callback.createDelegate(scope) : callback,
			isForm: true
		});

		if(this.fireEvent('beforecall', this, t, m) !== false){
			Ext.Direct.addTransaction(t);
			var isUpload = String(form.getAttribute("enctype")).toLowerCase() == 'multipart/form-data',
			params = {
				extTID: t.tid,
				extAction: c,
				extMethod: m.name,
				extType: 'rpc',
				extUpload: String(isUpload)
			};



			Ext.apply(t, {
				form: Ext.getDom(form),
				isUpload: isUpload,
				params: callback && Ext.isObject(callback.params) ? Ext.apply(params, callback.params) : params
			});
			this.fireEvent('call', this, t, m);
			this.processForm(t);
		}
	},

	processForm: function(t){
		Ext.Ajax.request({
			url: this.url,
			params: t.params,
			callback: this.onData,
			scope: this,
			form: t.form,
			isUpload: t.isUpload,
			ts: t
		});
	},

	createMethod : function(c, m){
		var f;
		if(!m.formHandler){
			f = function(){
				this.doCall(c, m, Array.prototype.slice.call(arguments, 0));
			}.createDelegate(this);
		}else{
			f = function(form, callback, scope){
				this.doForm(c, m, form, callback, scope);
			}.createDelegate(this);
		}
		f.directCfg = {
			action: c,
			method: m
		};
		return f;
	},

	getTransaction: function(opt){
		return opt && opt.tid ? Ext.Direct.getTransaction(opt.tid) : null;
	},

	doCallback: function(t, e){
		var fn = e.status ? 'success' : 'failure';
		if(t && t.cb){
			var hs = t.cb,
			result = Ext.isDefined(e.result) ? e.result : e.data;
			if(Ext.isFunction(hs)){
				hs(result, e);
			} else{
				Ext.callback(hs[fn], hs.scope, [result, e]);
				Ext.callback(hs.callback, hs.scope, [result, e]);
			}
		}
	}
});
Ext.Direct.PROVIDERS['remoting'] = Ext.direct.RemotingProvider;
Ext.Resizable = Ext.extend(Ext.util.Observable, {

	constructor: function(el, config){
		this.el = Ext.get(el);
		if(config && config.wrap){
			config.resizeChild = this.el;
			this.el = this.el.wrap(typeof config.wrap == 'object' ? config.wrap : {
				cls:'xresizable-wrap'
			});
			this.el.id = this.el.dom.id = config.resizeChild.id + '-rzwrap';
			this.el.setStyle('overflow', 'hidden');
			this.el.setPositioning(config.resizeChild.getPositioning());
			config.resizeChild.clearPositioning();
			if(!config.width || !config.height){
				var csize = config.resizeChild.getSize();
				this.el.setSize(csize.width, csize.height);
			}
			if(config.pinned && !config.adjustments){
				config.adjustments = 'auto';
			}
		}


		this.proxy = this.el.createProxy({
			tag: 'div',
			cls: 'x-resizable-proxy',
			id: this.el.id + '-rzproxy'
			}, Ext.getBody());
		this.proxy.unselectable();
		this.proxy.enableDisplayMode('block');

		Ext.apply(this, config);

		if(this.pinned){
			this.disableTrackOver = true;
			this.el.addClass('x-resizable-pinned');
		}

		var position = this.el.getStyle('position');
		if(position != 'absolute' && position != 'fixed'){
			this.el.setStyle('position', 'relative');
		}
		if(!this.handles){
			this.handles = 's,e,se';
			if(this.multiDirectional){
				this.handles += ',n,w';
			}
		}
		if(this.handles == 'all'){
			this.handles = 'n s e w ne nw se sw';
		}
		var hs = this.handles.split(/\s*?[,;]\s*?| /);
		var ps = Ext.Resizable.positions;
		for(var i = 0, len = hs.length; i < len; i++){
			if(hs[i] && ps[hs[i]]){
				var pos = ps[hs[i]];
				this[pos] = new Ext.Resizable.Handle(this, pos, this.disableTrackOver, this.transparent, this.handleCls);
			}
		}

		this.corner = this.southeast;

		if(this.handles.indexOf('n') != -1 || this.handles.indexOf('w') != -1){
			this.updateBox = true;
		}

		this.activeHandle = null;

		if(this.resizeChild){
			if(typeof this.resizeChild == 'boolean'){
				this.resizeChild = Ext.get(this.el.dom.firstChild, true);
			}else{
				this.resizeChild = Ext.get(this.resizeChild, true);
			}
		}

		if(this.adjustments == 'auto'){
			var rc = this.resizeChild;
			var hw = this.west, he = this.east, hn = this.north, hs = this.south;
			if(rc && (hw || hn)){
				rc.position('relative');
				rc.setLeft(hw ? hw.el.getWidth() : 0);
				rc.setTop(hn ? hn.el.getHeight() : 0);
			}
			this.adjustments = [
			(he ? -he.el.getWidth() : 0) + (hw ? -hw.el.getWidth() : 0),
			(hn ? -hn.el.getHeight() : 0) + (hs ? -hs.el.getHeight() : 0) -1
			];
		}

		if(this.draggable){
			this.dd = this.dynamic ?
			this.el.initDD(null) : this.el.initDDProxy(null, {
				dragElId: this.proxy.id
				});
			this.dd.setHandleElId(this.resizeChild ? this.resizeChild.id : this.el.id);
			if(this.constrainTo){
				this.dd.constrainTo(this.constrainTo);
			}
		}

		this.addEvents(

			'beforeresize',

			'resize'
			);

		if(this.width !== null && this.height !== null){
			this.resizeTo(this.width, this.height);
		}else{
			this.updateChildSize();
		}
		if(Ext.isIE){
			this.el.dom.style.zoom = 1;
		}
		Ext.Resizable.superclass.constructor.call(this);
	},


	adjustments : [0, 0],

	animate : false,


	disableTrackOver : false,

	draggable: false,

	duration : 0.35,

	dynamic : false,

	easing : 'easeOutStrong',

	enabled : true,


	handles : false,

	multiDirectional : false,

	height : null,

	width : null,

	heightIncrement : 0,

	widthIncrement : 0,

	minHeight : 5,

	minWidth : 5,

	maxHeight : 10000,

	maxWidth : 10000,

	minX: 0,

	minY: 0,

	pinned : false,

	preserveRatio : false,

	resizeChild : false,

	transparent: false,






	resizeTo : function(width, height){
		this.el.setSize(width, height);
		this.updateChildSize();
		this.fireEvent('resize', this, width, height, null);
	},


	startSizing : function(e, handle){
		this.fireEvent('beforeresize', this, e);
		if(this.enabled){

			if(!this.overlay){
				this.overlay = this.el.createProxy({
					tag: 'div',
					cls: 'x-resizable-overlay',
					html: '&#160;'
				}, Ext.getBody());
				this.overlay.unselectable();
				this.overlay.enableDisplayMode('block');
				this.overlay.on({
					scope: this,
					mousemove: this.onMouseMove,
					mouseup: this.onMouseUp
				});
			}
			this.overlay.setStyle('cursor', handle.el.getStyle('cursor'));

			this.resizing = true;
			this.startBox = this.el.getBox();
			this.startPoint = e.getXY();
			this.offsets = [(this.startBox.x + this.startBox.width) - this.startPoint[0],
			(this.startBox.y + this.startBox.height) - this.startPoint[1]];

			this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
			this.overlay.show();

			if(this.constrainTo) {
				var ct = Ext.get(this.constrainTo);
				this.resizeRegion = ct.getRegion().adjust(
					ct.getFrameWidth('t'),
					ct.getFrameWidth('l'),
					-ct.getFrameWidth('b'),
					-ct.getFrameWidth('r')
					);
			}

			this.proxy.setStyle('visibility', 'hidden');
			this.proxy.show();
			this.proxy.setBox(this.startBox);
			if(!this.dynamic){
				this.proxy.setStyle('visibility', 'visible');
			}
		}
	},


	onMouseDown : function(handle, e){
		if(this.enabled){
			e.stopEvent();
			this.activeHandle = handle;
			this.startSizing(e, handle);
		}
	},


	onMouseUp : function(e){
		this.activeHandle = null;
		var size = this.resizeElement();
		this.resizing = false;
		this.handleOut();
		this.overlay.hide();
		this.proxy.hide();
		this.fireEvent('resize', this, size.width, size.height, e);
	},


	updateChildSize : function(){
		if(this.resizeChild){
			var el = this.el;
			var child = this.resizeChild;
			var adj = this.adjustments;
			if(el.dom.offsetWidth){
				var b = el.getSize(true);
				child.setSize(b.width+adj[0], b.height+adj[1]);
			}




			if(Ext.isIE){
				setTimeout(function(){
					if(el.dom.offsetWidth){
						var b = el.getSize(true);
						child.setSize(b.width+adj[0], b.height+adj[1]);
					}
				}, 10);
			}
		}
	},


	snap : function(value, inc, min){
		if(!inc || !value){
			return value;
		}
		var newValue = value;
		var m = value % inc;
		if(m > 0){
			if(m > (inc/2)){
				newValue = value + (inc-m);
			}else{
				newValue = value - m;
			}
		}
		return Math.max(min, newValue);
	},


	resizeElement : function(){
		var box = this.proxy.getBox();
		if(this.updateBox){
			this.el.setBox(box, false, this.animate, this.duration, null, this.easing);
		}else{
			this.el.setSize(box.width, box.height, this.animate, this.duration, null, this.easing);
		}
		this.updateChildSize();
		if(!this.dynamic){
			this.proxy.hide();
		}
		if(this.draggable && this.constrainTo){
			this.dd.resetConstraints();
			this.dd.constrainTo(this.constrainTo);
		}
		return box;
	},


	constrain : function(v, diff, m, mx){
		if(v - diff < m){
			diff = v - m;
		}else if(v - diff > mx){
			diff = v - mx;
		}
		return diff;
	},


	onMouseMove : function(e){
		if(this.enabled && this.activeHandle){
			try{

				if(this.resizeRegion && !this.resizeRegion.contains(e.getPoint())) {
					return;
				}


				var curSize = this.curSize || this.startBox,
				x = this.startBox.x, y = this.startBox.y,
				ox = x,
				oy = y,
				w = curSize.width,
				h = curSize.height,
				ow = w,
				oh = h,
				mw = this.minWidth,
				mh = this.minHeight,
				mxw = this.maxWidth,
				mxh = this.maxHeight,
				wi = this.widthIncrement,
				hi = this.heightIncrement,
				eventXY = e.getXY(),
				diffX = -(this.startPoint[0] - Math.max(this.minX, eventXY[0])),
				diffY = -(this.startPoint[1] - Math.max(this.minY, eventXY[1])),
				pos = this.activeHandle.position,
				tw,
				th;

				switch(pos){
					case 'east':
						w += diffX;
						w = Math.min(Math.max(mw, w), mxw);
						break;
					case 'south':
						h += diffY;
						h = Math.min(Math.max(mh, h), mxh);
						break;
					case 'southeast':
						w += diffX;
						h += diffY;
						w = Math.min(Math.max(mw, w), mxw);
						h = Math.min(Math.max(mh, h), mxh);
						break;
					case 'north':
						diffY = this.constrain(h, diffY, mh, mxh);
						y += diffY;
						h -= diffY;
						break;
					case 'west':
						diffX = this.constrain(w, diffX, mw, mxw);
						x += diffX;
						w -= diffX;
						break;
					case 'northeast':
						w += diffX;
						w = Math.min(Math.max(mw, w), mxw);
						diffY = this.constrain(h, diffY, mh, mxh);
						y += diffY;
						h -= diffY;
						break;
					case 'northwest':
						diffX = this.constrain(w, diffX, mw, mxw);
						diffY = this.constrain(h, diffY, mh, mxh);
						y += diffY;
						h -= diffY;
						x += diffX;
						w -= diffX;
						break;
					case 'southwest':
						diffX = this.constrain(w, diffX, mw, mxw);
						h += diffY;
						h = Math.min(Math.max(mh, h), mxh);
						x += diffX;
						w -= diffX;
						break;
				}

				var sw = this.snap(w, wi, mw);
				var sh = this.snap(h, hi, mh);
				if(sw != w || sh != h){
					switch(pos){
						case 'northeast':
							y -= sh - h;
							break;
						case 'north':
							y -= sh - h;
							break;
						case 'southwest':
							x -= sw - w;
							break;
						case 'west':
							x -= sw - w;
							break;
						case 'northwest':
							x -= sw - w;
							y -= sh - h;
							break;
					}
					w = sw;
					h = sh;
				}

				if(this.preserveRatio){
					switch(pos){
						case 'southeast':
						case 'east':
							h = oh * (w/ow);
							h = Math.min(Math.max(mh, h), mxh);
							w = ow * (h/oh);
							break;
						case 'south':
							w = ow * (h/oh);
							w = Math.min(Math.max(mw, w), mxw);
							h = oh * (w/ow);
							break;
						case 'northeast':
							w = ow * (h/oh);
							w = Math.min(Math.max(mw, w), mxw);
							h = oh * (w/ow);
							break;
						case 'north':
							tw = w;
							w = ow * (h/oh);
							w = Math.min(Math.max(mw, w), mxw);
							h = oh * (w/ow);
							x += (tw - w) / 2;
							break;
						case 'southwest':
							h = oh * (w/ow);
							h = Math.min(Math.max(mh, h), mxh);
							tw = w;
							w = ow * (h/oh);
							x += tw - w;
							break;
						case 'west':
							th = h;
							h = oh * (w/ow);
							h = Math.min(Math.max(mh, h), mxh);
							y += (th - h) / 2;
							tw = w;
							w = ow * (h/oh);
							x += tw - w;
							break;
						case 'northwest':
							tw = w;
							th = h;
							h = oh * (w/ow);
							h = Math.min(Math.max(mh, h), mxh);
							w = ow * (h/oh);
							y += th - h;
							x += tw - w;
							break;

					}
				}
				this.proxy.setBounds(x, y, w, h);
				if(this.dynamic){
					this.resizeElement();
				}
			}catch(ex){}
		}
	},


	handleOver : function(){
		if(this.enabled){
			this.el.addClass('x-resizable-over');
		}
	},


	handleOut : function(){
		if(!this.resizing){
			this.el.removeClass('x-resizable-over');
		}
	},


	getEl : function(){
		return this.el;
	},


	getResizeChild : function(){
		return this.resizeChild;
	},


	destroy : function(removeEl){
		Ext.destroy(this.dd, this.overlay, this.proxy);
		this.overlay = null;
		this.proxy = null;

		var ps = Ext.Resizable.positions;
		for(var k in ps){
			if(typeof ps[k] != 'function' && this[ps[k]]){
				this[ps[k]].destroy();
			}
		}
		if(removeEl){
			this.el.update('');
			Ext.destroy(this.el);
			this.el = null;
		}
		this.purgeListeners();
	},

	syncHandleHeight : function(){
		var h = this.el.getHeight(true);
		if(this.west){
			this.west.el.setHeight(h);
		}
		if(this.east){
			this.east.el.setHeight(h);
		}
	}
});



Ext.Resizable.positions = {
	n: 'north',
	s: 'south',
	e: 'east',
	w: 'west',
	se: 'southeast',
	sw: 'southwest',
	nw: 'northwest',
	ne: 'northeast'
};

Ext.Resizable.Handle = Ext.extend(Object, {
	constructor : function(rz, pos, disableTrackOver, transparent, cls){
		if(!this.tpl){

			var tpl = Ext.DomHelper.createTemplate(
			{
				tag: 'div',
				cls: 'x-resizable-handle x-resizable-handle-{0}'
			}
			);
			tpl.compile();
			Ext.Resizable.Handle.prototype.tpl = tpl;
		}
		this.position = pos;
		this.rz = rz;
		this.el = this.tpl.append(rz.el.dom, [this.position], true);
		this.el.unselectable();
		if(transparent){
			this.el.setOpacity(0);
		}
		if(!Ext.isEmpty(cls)){
			this.el.addClass(cls);
		}
		this.el.on('mousedown', this.onMouseDown, this);
		if(!disableTrackOver){
			this.el.on({
				scope: this,
				mouseover: this.onMouseOver,
				mouseout: this.onMouseOut
			});
		}
	},


	afterResize : function(rz){

	},

	onMouseDown : function(e){
		this.rz.onMouseDown(this, e);
	},

	onMouseOver : function(e){
		this.rz.handleOver(this, e);
	},

	onMouseOut : function(e){
		this.rz.handleOut(this, e);
	},

	destroy : function(){
		Ext.destroy(this.el);
		this.el = null;
	}
});

Ext.Window = Ext.extend(Ext.Panel, {












	baseCls : 'x-window',

	resizable : true,

	draggable : true,

	closable : true,

	closeAction : 'close',

	constrain : false,

	constrainHeader : false,

	plain : false,

	minimizable : false,

	maximizable : false,

	minHeight : 100,

	minWidth : 200,

	expandOnShow : true,


	showAnimDuration: 0.25,


	hideAnimDuration: 0.25,


	collapsible : false,


	initHidden : undefined,


	hidden : true,






	elements : 'header,body',

	frame : true,

	floating : true,


	initComponent : function(){
		this.initTools();
		Ext.Window.superclass.initComponent.call(this);
		this.addEvents(



			'resize',

			'maximize',

			'minimize',

			'restore'
			);

		if(Ext.isDefined(this.initHidden)){
			this.hidden = this.initHidden;
		}
		if(this.hidden === false){
			this.hidden = true;
			this.show();
		}
	},


	getState : function(){
		return Ext.apply(Ext.Window.superclass.getState.call(this) || {}, this.getBox(true));
	},


	onRender : function(ct, position){
		Ext.Window.superclass.onRender.call(this, ct, position);

		if(this.plain){
			this.el.addClass('x-window-plain');
		}


		this.focusEl = this.el.createChild({
			tag: 'a',
			href:'#',
			cls:'x-dlg-focus',
			tabIndex:'-1',
			html: '&#160;'
		});
		this.focusEl.swallowEvent('click', true);

		this.proxy = this.el.createProxy('x-window-proxy');
		this.proxy.enableDisplayMode('block');

		if(this.modal){
			this.mask = this.container.createChild({
				cls:'ext-el-mask'
			}, this.el.dom);
			this.mask.enableDisplayMode('block');
			this.mask.hide();
			this.mon(this.mask, 'click', this.focus, this);
		}
		if(this.maximizable){
			this.mon(this.header, 'dblclick', this.toggleMaximize, this);
		}
	},


	initEvents : function(){
		Ext.Window.superclass.initEvents.call(this);
		if(this.animateTarget){
			this.setAnimateTarget(this.animateTarget);
		}

		if(this.resizable){
			this.resizer = new Ext.Resizable(this.el, {
				minWidth: this.minWidth,
				minHeight:this.minHeight,
				handles: this.resizeHandles || 'all',
				pinned: true,
				resizeElement : this.resizerAction,
				handleCls: 'x-window-handle'
			});
			this.resizer.window = this;
			this.mon(this.resizer, 'beforeresize', this.beforeResize, this);
		}

		if(this.draggable){
			this.header.addClass('x-window-draggable');
		}
		this.mon(this.el, 'mousedown', this.toFront, this);
		this.manager = this.manager || Ext.WindowMgr;
		this.manager.register(this);
		if(this.maximized){
			this.maximized = false;
			this.maximize();
		}
		if(this.closable){
			var km = this.getKeyMap();
			km.on(27, this.onEsc, this);
			km.disable();
		}
	},

	initDraggable : function(){

		this.dd = new Ext.Window.DD(this);
	},


	onEsc : function(k, e){
		e.stopEvent();
		this[this.closeAction]();
	},


	beforeDestroy : function(){
		if(this.rendered){
			this.hide();
			this.clearAnchor();
			Ext.destroy(
				this.focusEl,
				this.resizer,
				this.dd,
				this.proxy,
				this.mask
				);
		}
		Ext.Window.superclass.beforeDestroy.call(this);
	},


	onDestroy : function(){
		if(this.manager){
			this.manager.unregister(this);
		}
		Ext.Window.superclass.onDestroy.call(this);
	},


	initTools : function(){
		if(this.minimizable){
			this.addTool({
				id: 'minimize',
				handler: this.minimize.createDelegate(this, [])
			});
		}
		if(this.maximizable){
			this.addTool({
				id: 'maximize',
				handler: this.maximize.createDelegate(this, [])
			});
			this.addTool({
				id: 'restore',
				handler: this.restore.createDelegate(this, []),
				hidden:true
			});
		}
		if(this.closable){
			this.addTool({
				id: 'close',
				handler: this[this.closeAction].createDelegate(this, [])
			});
		}
	},


	resizerAction : function(){
		var box = this.proxy.getBox();
		this.proxy.hide();
		this.window.handleResize(box);
		return box;
	},


	beforeResize : function(){
		this.resizer.minHeight = Math.max(this.minHeight, this.getFrameHeight() + 40);
		this.resizer.minWidth = Math.max(this.minWidth, this.getFrameWidth() + 40);
		this.resizeBox = this.el.getBox();
	},


	updateHandles : function(){
		if(Ext.isIE && this.resizer){
			this.resizer.syncHandleHeight();
			this.el.repaint();
		}
	},


	handleResize : function(box){
		var rz = this.resizeBox;
		if(rz.x != box.x || rz.y != box.y){
			this.updateBox(box);
		}else{
			this.setSize(box);
			if (Ext.isIE6 && Ext.isStrict) {
				this.doLayout();
			}
		}
		this.focus();
		this.updateHandles();
		this.saveState();
	},


	focus : function(){
		var f = this.focusEl,
		db = this.defaultButton,
		t = typeof db,
		el,
		ct;
		if(Ext.isDefined(db)){
			if(Ext.isNumber(db) && this.fbar){
				f = this.fbar.items.get(db);
			}else if(Ext.isString(db)){
				f = Ext.getCmp(db);
			}else{
				f = db;
			}
			el = f.getEl();
			ct = Ext.getDom(this.container);
			if (el && ct) {
				if (ct != document.body && !Ext.lib.Region.getRegion(ct).contains(Ext.lib.Region.getRegion(el.dom))){
					return;
				}
			}
		}
		f = f || this.focusEl;
		f.focus.defer(10, f);
	},


	setAnimateTarget : function(el){
		el = Ext.get(el);
		this.animateTarget = el;
	},


	beforeShow : function(){
		delete this.el.lastXY;
		delete this.el.lastLT;
		if(this.x === undefined || this.y === undefined){
			var xy = this.el.getAlignToXY(this.container, 'c-c');
			var pos = this.el.translatePoints(xy[0], xy[1]);
			this.x = this.x === undefined? pos.left : this.x;
			this.y = this.y === undefined? pos.top : this.y;
		}
		this.el.setLeftTop(this.x, this.y);

		if(this.expandOnShow){
			this.expand(false);
		}

		if(this.modal){
			Ext.getBody().addClass('x-body-masked');
			this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
			this.mask.show();
		}
	},


	show : function(animateTarget, cb, scope){
		if(!this.rendered){
			this.render(Ext.getBody());
		}
		if(this.hidden === false){
			this.toFront();
			return this;
		}
		if(this.fireEvent('beforeshow', this) === false){
			return this;
		}
		if(cb){
			this.on('show', cb, scope, {
				single:true
			});
		}
		this.hidden = false;
		if(Ext.isDefined(animateTarget)){
			this.setAnimateTarget(animateTarget);
		}
		this.beforeShow();
		if(this.animateTarget){
			this.animShow();
		}else{
			this.afterShow();
		}
		return this;
	},


	afterShow : function(isAnim){
		if (this.isDestroyed){
			return false;
		}
		this.proxy.hide();
		this.el.setStyle('display', 'block');
		this.el.show();
		if(this.maximized){
			this.fitContainer();
		}
		if(Ext.isMac && Ext.isGecko2){
			this.cascade(this.setAutoScroll);
		}

		if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
			Ext.EventManager.onWindowResize(this.onWindowResize, this);
		}
		this.doConstrain();
		this.doLayout();
		if(this.keyMap){
			this.keyMap.enable();
		}
		this.toFront();
		this.updateHandles();
		if(isAnim && (Ext.isIE || Ext.isWebKit)){
			var sz = this.getSize();
			this.onResize(sz.width, sz.height);
		}
		this.onShow();
		this.fireEvent('show', this);
	},


	animShow : function(){
		this.proxy.show();
		this.proxy.setBox(this.animateTarget.getBox());
		this.proxy.setOpacity(0);
		var b = this.getBox();
		this.el.setStyle('display', 'none');
		this.proxy.shift(Ext.apply(b, {
			callback: this.afterShow.createDelegate(this, [true], false),
			scope: this,
			easing: 'easeNone',
			duration: this.showAnimDuration,
			opacity: 0.5
		}));
	},


	hide : function(animateTarget, cb, scope){
		if(this.hidden || this.fireEvent('beforehide', this) === false){
			return this;
		}
		if(cb){
			this.on('hide', cb, scope, {
				single:true
			});
		}
		this.hidden = true;
		if(animateTarget !== undefined){
			this.setAnimateTarget(animateTarget);
		}
		if(this.modal){
			this.mask.hide();
			Ext.getBody().removeClass('x-body-masked');
		}
		if(this.animateTarget){
			this.animHide();
		}else{
			this.el.hide();
			this.afterHide();
		}
		return this;
	},


	afterHide : function(){
		this.proxy.hide();
		if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
			Ext.EventManager.removeResizeListener(this.onWindowResize, this);
		}
		if(this.keyMap){
			this.keyMap.disable();
		}
		this.onHide();
		this.fireEvent('hide', this);
	},


	animHide : function(){
		this.proxy.setOpacity(0.5);
		this.proxy.show();
		var tb = this.getBox(false);
		this.proxy.setBox(tb);
		this.el.hide();
		this.proxy.shift(Ext.apply(this.animateTarget.getBox(), {
			callback: this.afterHide,
			scope: this,
			duration: this.hideAnimDuration,
			easing: 'easeNone',
			opacity: 0
		}));
	},


	onShow : Ext.emptyFn,


	onHide : Ext.emptyFn,


	onWindowResize : function(){
		if(this.maximized){
			this.fitContainer();
		}
		if(this.modal){
			this.mask.setSize('100%', '100%');
			var force = this.mask.dom.offsetHeight;
			this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
		}
		this.doConstrain();
	},


	doConstrain : function(){
		if(this.constrain || this.constrainHeader){
			var offsets;
			if(this.constrain){
				offsets = {
					right:this.el.shadowOffset,
					left:this.el.shadowOffset,
					bottom:this.el.shadowOffset
				};
			}else {
				var s = this.getSize();
				offsets = {
					right:-(s.width - 100),
					bottom:-(s.height - 25)
				};
			}

			var xy = this.el.getConstrainToXY(this.container, true, offsets);
			if(xy){
				this.setPosition(xy[0], xy[1]);
			}
		}
	},


	ghost : function(cls){
		var ghost = this.createGhost(cls);
		var box = this.getBox(true);
		ghost.setLeftTop(box.x, box.y);
		ghost.setWidth(box.width);
		this.el.hide();
		this.activeGhost = ghost;
		return ghost;
	},


	unghost : function(show, matchPosition){
		if(!this.activeGhost) {
			return;
		}
		if(show !== false){
			this.el.show();
			this.focus.defer(10, this);
			if(Ext.isMac && Ext.isGecko2){
				this.cascade(this.setAutoScroll);
			}
		}
		if(matchPosition !== false){
			this.setPosition(this.activeGhost.getLeft(true), this.activeGhost.getTop(true));
		}
		this.activeGhost.hide();
		this.activeGhost.remove();
		delete this.activeGhost;
	},


	minimize : function(){
		this.fireEvent('minimize', this);
		return this;
	},


	close : function(){
		if(this.fireEvent('beforeclose', this) !== false){
			if(this.hidden){
				this.doClose();
			}else{
				this.hide(null, this.doClose, this);
			}
		}
	},


	doClose : function(){
		this.fireEvent('close', this);
		this.destroy();
	},


	maximize : function(){
		if(!this.maximized){
			this.expand(false);
			this.restoreSize = this.getSize();
			this.restorePos = this.getPosition(true);
			if (this.maximizable){
				this.tools.maximize.hide();
				this.tools.restore.show();
			}
			this.maximized = true;
			this.el.disableShadow();

			if(this.dd){
				this.dd.lock();
			}
			if(this.collapsible){
				this.tools.toggle.hide();
			}
			this.el.addClass('x-window-maximized');
			this.container.addClass('x-window-maximized-ct');

			this.setPosition(0, 0);
			this.fitContainer();
			this.fireEvent('maximize', this);
		}
		return this;
	},


	restore : function(){
		if(this.maximized){
			var t = this.tools;
			this.el.removeClass('x-window-maximized');
			if(t.restore){
				t.restore.hide();
			}
			if(t.maximize){
				t.maximize.show();
			}
			this.setPosition(this.restorePos[0], this.restorePos[1]);
			this.setSize(this.restoreSize.width, this.restoreSize.height);
			delete this.restorePos;
			delete this.restoreSize;
			this.maximized = false;
			this.el.enableShadow(true);

			if(this.dd){
				this.dd.unlock();
			}
			if(this.collapsible && t.toggle){
				t.toggle.show();
			}
			this.container.removeClass('x-window-maximized-ct');

			this.doConstrain();
			this.fireEvent('restore', this);
		}
		return this;
	},


	toggleMaximize : function(){
		return this[this.maximized ? 'restore' : 'maximize']();
	},


	fitContainer : function(){
		var vs = this.container.getViewSize(false);
		this.setSize(vs.width, vs.height);
	},



	setZIndex : function(index){
		if(this.modal){
			this.mask.setStyle('z-index', index);
		}
		this.el.setZIndex(++index);
		index += 5;

		if(this.resizer){
			this.resizer.proxy.setStyle('z-index', ++index);
		}

		this.lastZIndex = index;
	},


	alignTo : function(element, position, offsets){
		var xy = this.el.getAlignToXY(element, position, offsets);
		this.setPagePosition(xy[0], xy[1]);
		return this;
	},


	anchorTo : function(el, alignment, offsets, monitorScroll){
		this.clearAnchor();
		this.anchorTarget = {
			el: el,
			alignment: alignment,
			offsets: offsets
		};

		Ext.EventManager.onWindowResize(this.doAnchor, this);
		var tm = typeof monitorScroll;
		if(tm != 'undefined'){
			Ext.EventManager.on(window, 'scroll', this.doAnchor, this,
			{
				buffer: tm == 'number' ? monitorScroll : 50
				});
		}
		return this.doAnchor();
	},


	doAnchor : function(){
		var o = this.anchorTarget;
		this.alignTo(o.el, o.alignment, o.offsets);
		return this;
	},


	clearAnchor : function(){
		if(this.anchorTarget){
			Ext.EventManager.removeResizeListener(this.doAnchor, this);
			Ext.EventManager.un(window, 'scroll', this.doAnchor, this);
			delete this.anchorTarget;
		}
		return this;
	},


	toFront : function(e){
		if(this.manager.bringToFront(this)){
			if(!e || !e.getTarget().focus){
				this.focus();
			}
		}
		return this;
	},


	setActive : function(active){
		if(active){
			if(!this.maximized){
				this.el.enableShadow(true);
			}
			this.fireEvent('activate', this);
		}else{
			this.el.disableShadow();
			this.fireEvent('deactivate', this);
		}
	},


	toBack : function(){
		this.manager.sendToBack(this);
		return this;
	},


	center : function(){
		var xy = this.el.getAlignToXY(this.container, 'c-c');
		this.setPagePosition(xy[0], xy[1]);
		return this;
	}


});
Ext.reg('window', Ext.Window);


Ext.Window.DD = Ext.extend(Ext.dd.DD, {

	constructor : function(win){
		this.win = win;
		Ext.Window.DD.superclass.constructor.call(this, win.el.id, 'WindowDD-'+win.id);
		this.setHandleElId(win.header.id);
		this.scroll = false;
	},

	moveOnly:true,
	headerOffsets:[100, 25],
	startDrag : function(){
		var w = this.win;
		this.proxy = w.ghost(w.initialConfig.cls);
		if(w.constrain !== false){
			var so = w.el.shadowOffset;
			this.constrainTo(w.container, {
				right: so,
				left: so,
				bottom: so
			});
		}else if(w.constrainHeader !== false){
			var s = this.proxy.getSize();
			this.constrainTo(w.container, {
				right: -(s.width-this.headerOffsets[0]),
				bottom: -(s.height-this.headerOffsets[1])
				});
		}
	},
	b4Drag : Ext.emptyFn,

	onDrag : function(e){
		this.alignElWithMouse(this.proxy, e.getPageX(), e.getPageY());
	},

	endDrag : function(e){
		this.win.unghost();
		this.win.saveState();
	}
});

Ext.WindowGroup = function(){
	var list = {};
	var accessList = [];
	var front = null;


	var sortWindows = function(d1, d2){
		return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1;
	};


	var orderWindows = function(){
		var a = accessList, len = a.length;
		if(len > 0){
			a.sort(sortWindows);
			var seed = a[0].manager.zseed;
			for(var i = 0; i < len; i++){
				var win = a[i];
				if(win && !win.hidden){
					win.setZIndex(seed + (i*10));
				}
			}
		}
		activateLast();
	};


	var setActiveWin = function(win){
		if(win != front){
			if(front){
				front.setActive(false);
			}
			front = win;
			if(win){
				win.setActive(true);
			}
		}
	};


	var activateLast = function(){
		for(var i = accessList.length-1; i >=0; --i) {
			if(!accessList[i].hidden){
				setActiveWin(accessList[i]);
				return;
			}
		}

		setActiveWin(null);
	};

	return {

		zseed : 9000,


		register : function(win){
			if(win.manager){
				win.manager.unregister(win);
			}
			win.manager = this;

			list[win.id] = win;
			accessList.push(win);
			win.on('hide', activateLast);
		},


		unregister : function(win){
			delete win.manager;
			delete list[win.id];
			win.un('hide', activateLast);
			accessList.remove(win);
		},


		get : function(id){
			return typeof id == "object" ? id : list[id];
		},


		bringToFront : function(win){
			win = this.get(win);
			if(win != front){
				win._lastAccess = new Date().getTime();
				orderWindows();
				return true;
			}
			return false;
		},


		sendToBack : function(win){
			win = this.get(win);
			win._lastAccess = -(new Date().getTime());
			orderWindows();
			return win;
		},


		hideAll : function(){
			for(var id in list){
				if(list[id] && typeof list[id] != "function" && list[id].isVisible()){
					list[id].hide();
				}
			}
		},


		getActive : function(){
			return front;
		},


		getBy : function(fn, scope){
			var r = [];
			for(var i = accessList.length-1; i >=0; --i) {
				var win = accessList[i];
				if(fn.call(scope||win, win) !== false){
					r.push(win);
				}
			}
			return r;
		},


		each : function(fn, scope){
			for(var id in list){
				if(list[id] && typeof list[id] != "function"){
					if(fn.call(scope || list[id], list[id]) === false){
						return;
					}
				}
			}
		}
	};
};



Ext.WindowMgr = new Ext.WindowGroup();
Ext.MessageBox = function(){
	var dlg, opt, mask, waitTimer,
	bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl,
	buttons, activeTextEl, bwidth, bufferIcon = '', iconCls = '',
	buttonNames = ['ok', 'yes', 'no', 'cancel'];


	var handleButton = function(button){
		buttons[button].blur();
		if(dlg.isVisible()){
			dlg.hide();
			handleHide();
			Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value, opt], 1);
		}
	};


	var handleHide = function(){
		if(opt && opt.cls){
			dlg.el.removeClass(opt.cls);
		}
		progressBar.reset();
	};


	var handleEsc = function(d, k, e){
		if(opt && opt.closable !== false){
			dlg.hide();
			handleHide();
		}
		if(e){
			e.stopEvent();
		}
	};


	var updateButtons = function(b){
		var width = 0,
		cfg;
		if(!b){
			Ext.each(buttonNames, function(name){
				buttons[name].hide();
			});
			return width;
		}
		dlg.footer.dom.style.display = '';
		Ext.iterate(buttons, function(name, btn){
			cfg = b[name];
			if(cfg){
				btn.show();
				btn.setText(Ext.isString(cfg) ? cfg : Ext.MessageBox.buttonText[name]);
				width += btn.getEl().getWidth() + 15;
			}else{
				btn.hide();
			}
		});
		return width;
	};

	return {

		getDialog : function(titleText){
			if(!dlg){
				var btns = [];

				buttons = {};
				Ext.each(buttonNames, function(name){
					btns.push(buttons[name] = new Ext.Button({
						text: this.buttonText[name],
						handler: handleButton.createCallback(name),
						hideMode: 'offsets'
					}));
				}, this);
				dlg = new Ext.Window({
					autoCreate : true,
					title:titleText,
					resizable:false,
					constrain:true,
					constrainHeader:true,
					minimizable : false,
					maximizable : false,
					stateful: false,
					modal: true,
					shim:true,
					buttonAlign:"center",
					width:400,
					height:100,
					minHeight: 80,
					plain:true,
					footer:true,
					closable:true,
					close : function(){
						if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){
							handleButton("no");
						}else{
							handleButton("cancel");
						}
					},
					fbar: new Ext.Toolbar({
						items: btns,
						enableOverflow: false
					})
				});
				dlg.render(document.body);
				dlg.getEl().addClass('x-window-dlg');
				mask = dlg.mask;
				bodyEl = dlg.body.createChild({
					html:'<div class="ext-mb-icon"></div><div class="ext-mb-content"><span class="ext-mb-text"></span><br /><div class="ext-mb-fix-cursor"><input type="text" class="ext-mb-input" /><textarea class="ext-mb-textarea"></textarea></div></div>'
				});
				iconEl = Ext.get(bodyEl.dom.firstChild);
				var contentEl = bodyEl.dom.childNodes[1];
				msgEl = Ext.get(contentEl.firstChild);
				textboxEl = Ext.get(contentEl.childNodes[2].firstChild);
				textboxEl.enableDisplayMode();
				textboxEl.addKeyListener([10,13], function(){
					if(dlg.isVisible() && opt && opt.buttons){
						if(opt.buttons.ok){
							handleButton("ok");
						}else if(opt.buttons.yes){
							handleButton("yes");
						}
					}
				});
				textareaEl = Ext.get(contentEl.childNodes[2].childNodes[1]);
				textareaEl.enableDisplayMode();
				progressBar = new Ext.ProgressBar({
					renderTo:bodyEl
				});
				bodyEl.createChild({
					cls:'x-clear'
				});
			}
			return dlg;
		},


		updateText : function(text){
			if(!dlg.isVisible() && !opt.width){
				dlg.setSize(this.maxWidth, 100);
			}

			msgEl.update(text ? text + ' ' : '&#160;');

			var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0,
			mw = msgEl.getWidth() + msgEl.getMargins('lr'),
			fw = dlg.getFrameWidth('lr'),
			bw = dlg.body.getFrameWidth('lr'),
			w;

			w = Math.max(Math.min(opt.width || iw+mw+fw+bw, opt.maxWidth || this.maxWidth),
				Math.max(opt.minWidth || this.minWidth, bwidth || 0));

			if(opt.prompt === true){
				activeTextEl.setWidth(w-iw-fw-bw);
			}
			if(opt.progress === true || opt.wait === true){
				progressBar.setSize(w-iw-fw-bw);
			}
			if(Ext.isIE && w == bwidth){
				w += 4;
			}
			msgEl.update(text || '&#160;');
			dlg.setSize(w, 'auto').center();
			return this;
		},


		updateProgress : function(value, progressText, msg){
			progressBar.updateProgress(value, progressText);
			if(msg){
				this.updateText(msg);
			}
			return this;
		},


		isVisible : function(){
			return dlg && dlg.isVisible();
		},


		hide : function(){
			var proxy = dlg ? dlg.activeGhost : null;
			if(this.isVisible() || proxy){
				dlg.hide();
				handleHide();
				if (proxy){


					dlg.unghost(false, false);
				}
			}
			return this;
		},


		show : function(options){
			if(this.isVisible()){
				this.hide();
			}
			opt = options;
			var d = this.getDialog(opt.title || "&#160;");

			d.setTitle(opt.title || "&#160;");
			var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true);
			d.tools.close.setDisplayed(allowClose);
			activeTextEl = textboxEl;
			opt.prompt = opt.prompt || (opt.multiline ? true : false);
			if(opt.prompt){
				if(opt.multiline){
					textboxEl.hide();
					textareaEl.show();
					textareaEl.setHeight(Ext.isNumber(opt.multiline) ? opt.multiline : this.defaultTextHeight);
					activeTextEl = textareaEl;
				}else{
					textboxEl.show();
					textareaEl.hide();
				}
			}else{
				textboxEl.hide();
				textareaEl.hide();
			}
			activeTextEl.dom.value = opt.value || "";
			if(opt.prompt){
				d.focusEl = activeTextEl;
			}else{
				var bs = opt.buttons;
				var db = null;
				if(bs && bs.ok){
					db = buttons["ok"];
				}else if(bs && bs.yes){
					db = buttons["yes"];
				}
				if (db){
					d.focusEl = db;
				}
			}
			if(Ext.isDefined(opt.iconCls)){
				d.setIconClass(opt.iconCls);
			}
			this.setIcon(Ext.isDefined(opt.icon) ? opt.icon : bufferIcon);
			bwidth = updateButtons(opt.buttons);
			progressBar.setVisible(opt.progress === true || opt.wait === true);
			this.updateProgress(0, opt.progressText);
			this.updateText(opt.msg);
			if(opt.cls){
				d.el.addClass(opt.cls);
			}
			d.proxyDrag = opt.proxyDrag === true;
			d.modal = opt.modal !== false;
			d.mask = opt.modal !== false ? mask : false;
			if(!d.isVisible()){

				document.body.appendChild(dlg.el.dom);
				d.setAnimateTarget(opt.animEl);

				d.on('show', function(){
					if(allowClose === true){
						d.keyMap.enable();
					}else{
						d.keyMap.disable();
					}
				}, this, {
					single:true
				});
				d.show(opt.animEl);
			}
			if(opt.wait === true){
				progressBar.wait(opt.waitConfig);
			}
			return this;
		},


		setIcon : function(icon){
			if(!dlg){
				bufferIcon = icon;
				return;
			}
			bufferIcon = undefined;
			if(icon && icon != ''){
				iconEl.removeClass('x-hidden');
				iconEl.replaceClass(iconCls, icon);
				bodyEl.addClass('x-dlg-icon');
				iconCls = icon;
			}else{
				iconEl.replaceClass(iconCls, 'x-hidden');
				bodyEl.removeClass('x-dlg-icon');
				iconCls = '';
			}
			return this;
		},


		progress : function(title, msg, progressText){
			this.show({
				title : title,
				msg : msg,
				buttons: false,
				progress:true,
				closable:false,
				minWidth: this.minProgressWidth,
				progressText: progressText
			});
			return this;
		},


		wait : function(msg, title, config){
			this.show({
				title : title,
				msg : msg,
				buttons: false,
				closable:false,
				wait:true,
				modal:true,
				minWidth: this.minProgressWidth,
				waitConfig: config
			});
			return this;
		},


		alert : function(title, msg, fn, scope){
			this.show({
				title : title,
				msg : msg,
				buttons: this.OK,
				fn: fn,
				scope : scope,
				minWidth: this.minWidth
			});
			return this;
		},


		confirm : function(title, msg, fn, scope){
			this.show({
				title : title,
				msg : msg,
				buttons: this.YESNO,
				fn: fn,
				scope : scope,
				icon: this.QUESTION,
				minWidth: this.minWidth
			});
			return this;
		},


		prompt : function(title, msg, fn, scope, multiline, value){
			this.show({
				title : title,
				msg : msg,
				buttons: this.OKCANCEL,
				fn: fn,
				minWidth: this.minPromptWidth,
				scope : scope,
				prompt:true,
				multiline: multiline,
				value: value
			});
			return this;
		},


		OK : {
			ok:true
		},

		CANCEL : {
			cancel:true
		},

		OKCANCEL : {
			ok:true,
			cancel:true
		},

		YESNO : {
			yes:true,
			no:true
		},

		YESNOCANCEL : {
			yes:true,
			no:true,
			cancel:true
		},

		INFO : 'ext-mb-info',

		WARNING : 'ext-mb-warning',

		QUESTION : 'ext-mb-question',

		ERROR : 'ext-mb-error',


		defaultTextHeight : 75,

		maxWidth : 600,

		minWidth : 100,

		minProgressWidth : 250,

		minPromptWidth: 250,

		buttonText : {
			ok : "OK",
			cancel : "Cancel",
			yes : "Yes",
			no : "No"
		}
	};
}();


Ext.Msg = Ext.MessageBox;
Ext.dd.PanelProxy  = Ext.extend(Object, {

	constructor : function(panel, config){
		this.panel = panel;
		this.id = this.panel.id +'-ddproxy';
		Ext.apply(this, config);
	},


	insertProxy : true,


	setStatus : Ext.emptyFn,
	reset : Ext.emptyFn,
	update : Ext.emptyFn,
	stop : Ext.emptyFn,
	sync: Ext.emptyFn,


	getEl : function(){
		return this.ghost;
	},


	getGhost : function(){
		return this.ghost;
	},


	getProxy : function(){
		return this.proxy;
	},


	hide : function(){
		if(this.ghost){
			if(this.proxy){
				this.proxy.remove();
				delete this.proxy;
			}
			this.panel.el.dom.style.display = '';
			this.ghost.remove();
			delete this.ghost;
		}
	},


	show : function(){
		if(!this.ghost){
			this.ghost = this.panel.createGhost(this.panel.initialConfig.cls, undefined, Ext.getBody());
			this.ghost.setXY(this.panel.el.getXY());
			if(this.insertProxy){
				this.proxy = this.panel.el.insertSibling({
					cls:'x-panel-dd-spacer'
				});
				this.proxy.setSize(this.panel.getSize());
			}
			this.panel.el.dom.style.display = 'none';
		}
	},


	repair : function(xy, callback, scope){
		this.hide();
		if(typeof callback == "function"){
			callback.call(scope || this);
		}
	},


	moveProxy : function(parentNode, before){
		if(this.proxy){
			parentNode.insertBefore(this.proxy.dom, before);
		}
	}
});


Ext.Panel.DD = Ext.extend(Ext.dd.DragSource, {

	constructor : function(panel, cfg){
		this.panel = panel;
		this.dragData = {
			panel: panel
		};
		this.proxy = new Ext.dd.PanelProxy(panel, cfg);
		Ext.Panel.DD.superclass.constructor.call(this, panel.el, cfg);
		var h = panel.header,
		el = panel.body;
		if(h){
			this.setHandleElId(h.id);
			el = panel.header;
		}
		el.setStyle('cursor', 'move');
		this.scroll = false;
	},

	showFrame: Ext.emptyFn,
	startDrag: Ext.emptyFn,
	b4StartDrag: function(x, y) {
		this.proxy.show();
	},
	b4MouseDown: function(e) {
		var x = e.getPageX(),
		y = e.getPageY();
		this.autoOffset(x, y);
	},
	onInitDrag : function(x, y){
		this.onStartDrag(x, y);
		return true;
	},
	createFrame : Ext.emptyFn,
	getDragEl : function(e){
		return this.proxy.ghost.dom;
	},
	endDrag : function(e){
		this.proxy.hide();
		this.panel.saveState();
	},

	autoOffset : function(x, y) {
		x -= this.startPageX;
		y -= this.startPageY;
		this.setDelta(x, y);
	}
});
Ext.state.Provider = Ext.extend(Ext.util.Observable, {

	constructor : function(){

		this.addEvents("statechange");
		this.state = {};
		Ext.state.Provider.superclass.constructor.call(this);
	},


	get : function(name, defaultValue){
		return typeof this.state[name] == "undefined" ?
		defaultValue : this.state[name];
	},


	clear : function(name){
		delete this.state[name];
		this.fireEvent("statechange", this, name, null);
	},


	set : function(name, value){
		this.state[name] = value;
		this.fireEvent("statechange", this, name, value);
	},


	decodeValue : function(cookie){

		var re = /^(a|n|d|b|s|o|e)\:(.*)$/,
		matches = re.exec(unescape(cookie)),
		all,
		type,
		v,
		kv;
		if(!matches || !matches[1]){
			return;
		}
		type = matches[1];
		v = matches[2];
		switch(type){
			case 'e':
				return null;
			case 'n':
				return parseFloat(v);
			case 'd':
				return new Date(Date.parse(v));
			case 'b':
				return (v == '1');
			case 'a':
				all = [];
				if(v != ''){
					Ext.each(v.split('^'), function(val){
						all.push(this.decodeValue(val));
					}, this);
				}
				return all;
			case 'o':
				all = {};
				if(v != ''){
					Ext.each(v.split('^'), function(val){
						kv = val.split('=');
						all[kv[0]] = this.decodeValue(kv[1]);
					}, this);
				}
				return all;
			default:
				return v;
		}
	},


	encodeValue : function(v){
		var enc,
		flat = '',
		i = 0,
		len,
		key;
		if(v == null){
			return 'e:1';
		}else if(typeof v == 'number'){
			enc = 'n:' + v;
		}else if(typeof v == 'boolean'){
			enc = 'b:' + (v ? '1' : '0');
		}else if(Ext.isDate(v)){
			enc = 'd:' + v.toGMTString();
		}else if(Ext.isArray(v)){
			for(len = v.length; i < len; i++){
				flat += this.encodeValue(v[i]);
				if(i != len - 1){
					flat += '^';
				}
			}
			enc = 'a:' + flat;
		}else if(typeof v == 'object'){
			for(key in v){
				if(typeof v[key] != 'function' && v[key] !== undefined){
					flat += key + '=' + this.encodeValue(v[key]) + '^';
				}
			}
			enc = 'o:' + flat.substring(0, flat.length-1);
		}else{
			enc = 's:' + v;
		}
		return escape(enc);
	}
});

Ext.state.Manager = function(){
	var provider = new Ext.state.Provider();

	return {

		setProvider : function(stateProvider){
			provider = stateProvider;
		},


		get : function(key, defaultValue){
			return provider.get(key, defaultValue);
		},


		set : function(key, value){
			provider.set(key, value);
		},


		clear : function(key){
			provider.clear(key);
		},


		getProvider : function(){
			return provider;
		}
	};
}();

Ext.state.CookieProvider = Ext.extend(Ext.state.Provider, {

	constructor : function(config){
		Ext.state.CookieProvider.superclass.constructor.call(this);
		this.path = "/";
		this.expires = new Date(new Date().getTime()+(1000*60*60*24*7));
		this.domain = null;
		this.secure = false;
		Ext.apply(this, config);
		this.state = this.readCookies();
	},


	set : function(name, value){
		if(typeof value == "undefined" || value === null){
			this.clear(name);
			return;
		}
		this.setCookie(name, value);
		Ext.state.CookieProvider.superclass.set.call(this, name, value);
	},


	clear : function(name){
		this.clearCookie(name);
		Ext.state.CookieProvider.superclass.clear.call(this, name);
	},


	readCookies : function(){
		var cookies = {},
		c = document.cookie + ";",
		re = /\s?(.*?)=(.*?);/g,
		matches,
		name,
		value;
		while((matches = re.exec(c)) != null){
			name = matches[1];
			value = matches[2];
			if(name && name.substring(0,3) == "ys-"){
				cookies[name.substr(3)] = this.decodeValue(value);
			}
		}
		return cookies;
	},


	setCookie : function(name, value){
		document.cookie = "ys-"+ name + "=" + this.encodeValue(value) +
		((this.expires == null) ? "" : ("; expires=" + this.expires.toGMTString())) +
		((this.path == null) ? "" : ("; path=" + this.path)) +
		((this.domain == null) ? "" : ("; domain=" + this.domain)) +
		((this.secure == true) ? "; secure" : "");
	},


	clearCookie : function(name){
		document.cookie = "ys-" + name + "=null; expires=Thu, 01-Jan-70 00:00:01 GMT" +
		((this.path == null) ? "" : ("; path=" + this.path)) +
		((this.domain == null) ? "" : ("; domain=" + this.domain)) +
		((this.secure == true) ? "; secure" : "");
	}
});
Ext.DataView = Ext.extend(Ext.BoxComponent, {









	selectedClass : "x-view-selected",

	emptyText : "",


	deferEmptyText: true,

	trackOver: false,


	blockRefresh: false,


	last: false,


	initComponent : function(){
		Ext.DataView.superclass.initComponent.call(this);
		if(Ext.isString(this.tpl) || Ext.isArray(this.tpl)){
			this.tpl = new Ext.XTemplate(this.tpl);
		}

		this.addEvents(

			"beforeclick",

			"click",

			"mouseenter",

			"mouseleave",

			"containerclick",

			"dblclick",

			"contextmenu",

			"containercontextmenu",

			"selectionchange",


			"beforeselect"
			);

		this.store = Ext.StoreMgr.lookup(this.store);
		this.all = new Ext.CompositeElementLite();
		this.selected = new Ext.CompositeElementLite();
	},


	afterRender : function(){
		Ext.DataView.superclass.afterRender.call(this);

		this.mon(this.getTemplateTarget(), {
			"click": this.onClick,
			"dblclick": this.onDblClick,
			"contextmenu": this.onContextMenu,
			scope:this
		});

		if(this.overClass || this.trackOver){
			this.mon(this.getTemplateTarget(), {
				"mouseover": this.onMouseOver,
				"mouseout": this.onMouseOut,
				scope:this
			});
		}

		if(this.store){
			this.bindStore(this.store, true);
		}
	},


	refresh : function() {
		this.clearSelections(false, true);
		var el = this.getTemplateTarget(),
		records = this.store.getRange();

		el.update('');
		if(records.length < 1){
			if(!this.deferEmptyText || this.hasSkippedEmptyText){
				el.update(this.emptyText);
			}
			this.all.clear();
		}else{
			this.tpl.overwrite(el, this.collectData(records, 0));
			this.all.fill(Ext.query(this.itemSelector, el.dom));
			this.updateIndexes(0);
		}
		this.hasSkippedEmptyText = true;
	},

	getTemplateTarget: function(){
		return this.el;
	},


	prepareData : function(data){
		return data;
	},


	collectData : function(records, startIndex){
		var r = [],
		i = 0,
		len = records.length;
		for(; i < len; i++){
			r[r.length] = this.prepareData(records[i].data, startIndex + i, records[i]);
		}
		return r;
	},


	bufferRender : function(records, index){
		var div = document.createElement('div');
		this.tpl.overwrite(div, this.collectData(records, index));
		return Ext.query(this.itemSelector, div);
	},


	onUpdate : function(ds, record){
		var index = this.store.indexOf(record);
		if(index > -1){
			var sel = this.isSelected(index),
			original = this.all.elements[index],
			node = this.bufferRender([record], index)[0];

			this.all.replaceElement(index, node, true);
			if(sel){
				this.selected.replaceElement(original, node);
				this.all.item(index).addClass(this.selectedClass);
			}
			this.updateIndexes(index, index);
		}
	},


	onAdd : function(ds, records, index){
		if(this.all.getCount() === 0){
			this.refresh();
			return;
		}
		var nodes = this.bufferRender(records, index), n, a = this.all.elements;
		if(index < this.all.getCount()){
			n = this.all.item(index).insertSibling(nodes, 'before', true);
			a.splice.apply(a, [index, 0].concat(nodes));
		}else{
			n = this.all.last().insertSibling(nodes, 'after', true);
			a.push.apply(a, nodes);
		}
		this.updateIndexes(index);
	},


	onRemove : function(ds, record, index){
		this.deselect(index);
		this.all.removeElement(index, true);
		this.updateIndexes(index);
		if (this.store.getCount() === 0){
			this.refresh();
		}
	},


	refreshNode : function(index){
		this.onUpdate(this.store, this.store.getAt(index));
	},


	updateIndexes : function(startIndex, endIndex){
		var ns = this.all.elements;
		startIndex = startIndex || 0;
		endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1));
		for(var i = startIndex; i <= endIndex; i++){
			ns[i].viewIndex = i;
		}
	},


	getStore : function(){
		return this.store;
	},


	bindStore : function(store, initial){
		if(!initial && this.store){
			if(store !== this.store && this.store.autoDestroy){
				this.store.destroy();
			}else{
				this.store.un("beforeload", this.onBeforeLoad, this);
				this.store.un("datachanged", this.onDataChanged, this);
				this.store.un("add", this.onAdd, this);
				this.store.un("remove", this.onRemove, this);
				this.store.un("update", this.onUpdate, this);
				this.store.un("clear", this.refresh, this);
			}
			if(!store){
				this.store = null;
			}
		}
		if(store){
			store = Ext.StoreMgr.lookup(store);
			store.on({
				scope: this,
				beforeload: this.onBeforeLoad,
				datachanged: this.onDataChanged,
				add: this.onAdd,
				remove: this.onRemove,
				update: this.onUpdate,
				clear: this.refresh
			});
		}
		this.store = store;
		if(store){
			this.refresh();
		}
	},


	onDataChanged: function() {
		if (this.blockRefresh !== true) {
			this.refresh.apply(this, arguments);
		}
	},


	findItemFromChild : function(node){
		return Ext.fly(node).findParent(this.itemSelector, this.getTemplateTarget());
	},


	onClick : function(e){
		var item = e.getTarget(this.itemSelector, this.getTemplateTarget()),
		index;
		if(item){
			index = this.indexOf(item);
			if(this.onItemClick(item, index, e) !== false){
				this.fireEvent("click", this, index, item, e);
			}
		}else{
			if(this.fireEvent("containerclick", this, e) !== false){
				this.onContainerClick(e);
			}
		}
	},

	onContainerClick : function(e){
		this.clearSelections();
	},


	onContextMenu : function(e){
		var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
		if(item){
			this.fireEvent("contextmenu", this, this.indexOf(item), item, e);
		}else{
			this.fireEvent("containercontextmenu", this, e);
		}
	},


	onDblClick : function(e){
		var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
		if(item){
			this.fireEvent("dblclick", this, this.indexOf(item), item, e);
		}
	},


	onMouseOver : function(e){
		var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
		if(item && item !== this.lastItem){
			this.lastItem = item;
			Ext.fly(item).addClass(this.overClass);
			this.fireEvent("mouseenter", this, this.indexOf(item), item, e);
		}
	},


	onMouseOut : function(e){
		if(this.lastItem){
			if(!e.within(this.lastItem, true, true)){
				Ext.fly(this.lastItem).removeClass(this.overClass);
				this.fireEvent("mouseleave", this, this.indexOf(this.lastItem), this.lastItem, e);
				delete this.lastItem;
			}
		}
	},


	onItemClick : function(item, index, e){
		if(this.fireEvent("beforeclick", this, index, item, e) === false){
			return false;
		}
		if(this.multiSelect){
			this.doMultiSelection(item, index, e);
			e.preventDefault();
		}else if(this.singleSelect){
			this.doSingleSelection(item, index, e);
			e.preventDefault();
		}
		return true;
	},


	doSingleSelection : function(item, index, e){
		if(e.ctrlKey && this.isSelected(index)){
			this.deselect(index);
		}else{
			this.select(index, false);
		}
	},


	doMultiSelection : function(item, index, e){
		if(e.shiftKey && this.last !== false){
			var last = this.last;
			this.selectRange(last, index, e.ctrlKey);
			this.last = last;
		}else{
			if((e.ctrlKey||this.simpleSelect) && this.isSelected(index)){
				this.deselect(index);
			}else{
				this.select(index, e.ctrlKey || e.shiftKey || this.simpleSelect);
			}
		}
	},


	getSelectionCount : function(){
		return this.selected.getCount();
	},


	getSelectedNodes : function(){
		return this.selected.elements;
	},


	getSelectedIndexes : function(){
		var indexes = [],
		selected = this.selected.elements,
		i = 0,
		len = selected.length;

		for(; i < len; i++){
			indexes.push(selected[i].viewIndex);
		}
		return indexes;
	},


	getSelectedRecords : function(){
		return this.getRecords(this.selected.elements);
	},


	getRecords : function(nodes){
		var records = [],
		i = 0,
		len = nodes.length;

		for(; i < len; i++){
			records[records.length] = this.store.getAt(nodes[i].viewIndex);
		}
		return records;
	},


	getRecord : function(node){
		return this.store.getAt(node.viewIndex);
	},


	clearSelections : function(suppressEvent, skipUpdate){
		if((this.multiSelect || this.singleSelect) && this.selected.getCount() > 0){
			if(!skipUpdate){
				this.selected.removeClass(this.selectedClass);
			}
			this.selected.clear();
			this.last = false;
			if(!suppressEvent){
				this.fireEvent("selectionchange", this, this.selected.elements);
			}
		}
	},


	isSelected : function(node){
		return this.selected.contains(this.getNode(node));
	},


	deselect : function(node){
		if(this.isSelected(node)){
			node = this.getNode(node);
			this.selected.removeElement(node);
			if(this.last == node.viewIndex){
				this.last = false;
			}
			Ext.fly(node).removeClass(this.selectedClass);
			this.fireEvent("selectionchange", this, this.selected.elements);
		}
	},


	select : function(nodeInfo, keepExisting, suppressEvent){
		if(Ext.isArray(nodeInfo)){
			if(!keepExisting){
				this.clearSelections(true);
			}
			for(var i = 0, len = nodeInfo.length; i < len; i++){
				this.select(nodeInfo[i], true, true);
			}
			if(!suppressEvent){
				this.fireEvent("selectionchange", this, this.selected.elements);
			}
		} else{
			var node = this.getNode(nodeInfo);
			if(!keepExisting){
				this.clearSelections(true);
			}
			if(node && !this.isSelected(node)){
				if(this.fireEvent("beforeselect", this, node, this.selected.elements) !== false){
					Ext.fly(node).addClass(this.selectedClass);
					this.selected.add(node);
					this.last = node.viewIndex;
					if(!suppressEvent){
						this.fireEvent("selectionchange", this, this.selected.elements);
					}
				}
			}
		}
	},


	selectRange : function(start, end, keepExisting){
		if(!keepExisting){
			this.clearSelections(true);
		}
		this.select(this.getNodes(start, end), true);
	},


	getNode : function(nodeInfo){
		if(Ext.isString(nodeInfo)){
			return document.getElementById(nodeInfo);
		}else if(Ext.isNumber(nodeInfo)){
			return this.all.elements[nodeInfo];
		}else if(nodeInfo instanceof Ext.data.Record){
			var idx = this.store.indexOf(nodeInfo);
			return this.all.elements[idx];
		}
		return nodeInfo;
	},


	getNodes : function(start, end){
		var ns = this.all.elements,
		nodes = [],
		i;

		start = start || 0;
		end = !Ext.isDefined(end) ? Math.max(ns.length - 1, 0) : end;
		if(start <= end){
			for(i = start; i <= end && ns[i]; i++){
				nodes.push(ns[i]);
			}
		} else{
			for(i = start; i >= end && ns[i]; i--){
				nodes.push(ns[i]);
			}
		}
		return nodes;
	},


	indexOf : function(node){
		node = this.getNode(node);
		if(Ext.isNumber(node.viewIndex)){
			return node.viewIndex;
		}
		return this.all.indexOf(node);
	},


	onBeforeLoad : function(){
		if(this.loadingText){
			this.clearSelections(false, true);
			this.getTemplateTarget().update('<div class="loading-indicator">'+this.loadingText+'</div>');
			this.all.clear();
		}
	},

	onDestroy : function(){
		this.all.clear();
		this.selected.clear();
		Ext.DataView.superclass.onDestroy.call(this);
		this.bindStore(null);
	}
});


Ext.DataView.prototype.setStore = Ext.DataView.prototype.bindStore;

Ext.reg('dataview', Ext.DataView);

Ext.list.ListView = Ext.extend(Ext.DataView, {



	itemSelector: 'dl',

	selectedClass:'x-list-selected',

	overClass:'x-list-over',


	scrollOffset : undefined,

	columnResize: true,


	columnSort: true,



	maxColumnWidth: Ext.isIE ? 99 : 100,

	initComponent : function(){
		if(this.columnResize){
			this.colResizer = new Ext.list.ColumnResizer(this.colResizer);
			this.colResizer.init(this);
		}
		if(this.columnSort){
			this.colSorter = new Ext.list.Sorter(this.columnSort);
			this.colSorter.init(this);
		}
		if(!this.internalTpl){
			this.internalTpl = new Ext.XTemplate(
				'<div class="x-list-header"><div class="x-list-header-inner">',
				'<tpl for="columns">',
				'<div style="width:{[values.width*100]}%;text-align:{align};"><em unselectable="on" id="',this.id, '-xlhd-{#}">',
				'{header}',
				'</em></div>',
				'</tpl>',
				'<div class="x-clear"></div>',
				'</div></div>',
				'<div class="x-list-body"><div class="x-list-body-inner">',
				'</div></div>'
				);
		}
		if(!this.tpl){
			this.tpl = new Ext.XTemplate(
				'<tpl for="rows">',
				'<dl>',
				'<tpl for="parent.columns">',
				'<dt style="width:{[values.width*100]}%;text-align:{align};">',
				'<em unselectable="on"<tpl if="cls"> class="{cls}</tpl>">',
				'{[values.tpl.apply(parent)]}',
				'</em></dt>',
				'</tpl>',
				'<div class="x-clear"></div>',
				'</dl>',
				'</tpl>'
				);
		};

		var cs = this.columns,
		allocatedWidth = 0,
		colsWithWidth = 0,
		len = cs.length,
		columns = [];

		for(var i = 0; i < len; i++){
			var c = cs[i];
			if(!c.isColumn) {
				c.xtype = c.xtype ? (/^lv/.test(c.xtype) ? c.xtype : 'lv' + c.xtype) : 'lvcolumn';
				c = Ext.create(c);
			}
			if(c.width) {
				allocatedWidth += c.width*100;
				if(allocatedWidth > this.maxColumnWidth){
					c.width -= (allocatedWidth - this.maxColumnWidth) / 100;
				}
				colsWithWidth++;
			}
			columns.push(c);
		}

		cs = this.columns = columns;


		if(colsWithWidth < len){
			var remaining = len - colsWithWidth;
			if(allocatedWidth < this.maxColumnWidth){
				var perCol = ((this.maxColumnWidth-allocatedWidth) / remaining)/100;
				for(var j = 0; j < len; j++){
					var c = cs[j];
					if(!c.width){
						c.width = perCol;
					}
				}
			}
		}
		Ext.list.ListView.superclass.initComponent.call(this);
	},

	onRender : function(){
		this.autoEl = {
			cls: 'x-list-wrap'
		};
		Ext.list.ListView.superclass.onRender.apply(this, arguments);

		this.internalTpl.overwrite(this.el, {
			columns: this.columns
			});

		this.innerBody = Ext.get(this.el.dom.childNodes[1].firstChild);
		this.innerHd = Ext.get(this.el.dom.firstChild.firstChild);

		if(this.hideHeaders){
			this.el.dom.firstChild.style.display = 'none';
		}
	},

	getTemplateTarget : function(){
		return this.innerBody;
	},


	collectData : function(){
		var rs = Ext.list.ListView.superclass.collectData.apply(this, arguments);
		return {
			columns: this.columns,
			rows: rs
		};
	},

	verifyInternalSize : function(){
		if(this.lastSize){
			this.onResize(this.lastSize.width, this.lastSize.height);
		}
	},


	onResize : function(w, h){
		var body = this.innerBody.dom,
		header = this.innerHd.dom,
		scrollWidth = w - Ext.num(this.scrollOffset, Ext.getScrollBarWidth()) + 'px',
		parentNode;

		if(!body){
			return;
		}
		parentNode = body.parentNode;
		if(Ext.isNumber(w)){
			if(this.reserveScrollOffset || ((parentNode.offsetWidth - parentNode.clientWidth) > 10)){
				body.style.width = scrollWidth;
				header.style.width = scrollWidth;
			}else{
				body.style.width = w + 'px';
				header.style.width = w + 'px';
				setTimeout(function(){
					if((parentNode.offsetWidth - parentNode.clientWidth) > 10){
						body.style.width = scrollWidth;
						header.style.width = scrollWidth;
					}
				}, 10);
			}
		}
		if(Ext.isNumber(h)){
			parentNode.style.height = Math.max(0, h - header.parentNode.offsetHeight) + 'px';
		}
	},

	updateIndexes : function(){
		Ext.list.ListView.superclass.updateIndexes.apply(this, arguments);
		this.verifyInternalSize();
	},

	findHeaderIndex : function(header){
		header = header.dom || header;
		var parentNode = header.parentNode,
		children = parentNode.parentNode.childNodes,
		i = 0,
		c;
		for(; c = children[i]; i++){
			if(c == parentNode){
				return i;
			}
		}
		return -1;
	},

	setHdWidths : function(){
		var els = this.innerHd.dom.getElementsByTagName('div'),
		i = 0,
		columns = this.columns,
		len = columns.length;

		for(; i < len; i++){
			els[i].style.width = (columns[i].width*100) + '%';
		}
	}
});

Ext.reg('listview', Ext.list.ListView);


Ext.ListView = Ext.list.ListView;
Ext.list.Column = Ext.extend(Object, {

	isColumn: true,


	align: 'left',

	header: '',


	width: null,


	cls: '',





	constructor : function(c){
		if(!c.tpl){
			c.tpl = new Ext.XTemplate('{' + c.dataIndex + '}');
		}
		else if(Ext.isString(c.tpl)){
			c.tpl = new Ext.XTemplate(c.tpl);
		}

		Ext.apply(this, c);
	}
});

Ext.reg('lvcolumn', Ext.list.Column);


Ext.list.NumberColumn = Ext.extend(Ext.list.Column, {

	format: '0,000.00',

	constructor : function(c) {
		c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':number("' + (c.format || this.format) + '")}');
		Ext.list.NumberColumn.superclass.constructor.call(this, c);
	}
});

Ext.reg('lvnumbercolumn', Ext.list.NumberColumn);


Ext.list.DateColumn = Ext.extend(Ext.list.Column, {
	format: 'm/d/Y',
	constructor : function(c) {
		c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':date("' + (c.format || this.format) + '")}');
		Ext.list.DateColumn.superclass.constructor.call(this, c);
	}
});
Ext.reg('lvdatecolumn', Ext.list.DateColumn);


Ext.list.BooleanColumn = Ext.extend(Ext.list.Column, {

	trueText: 'true',

	falseText: 'false',

	undefinedText: '&#160;',

	constructor : function(c) {
		c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':this.format}');

		var t = this.trueText, f = this.falseText, u = this.undefinedText;
		c.tpl.format = function(v){
			if(v === undefined){
				return u;
			}
			if(!v || v === 'false'){
				return f;
			}
			return t;
		};

		Ext.list.DateColumn.superclass.constructor.call(this, c);
	}
});

Ext.reg('lvbooleancolumn', Ext.list.BooleanColumn);
Ext.list.ColumnResizer = Ext.extend(Ext.util.Observable, {

	minPct: .05,

	constructor: function(config){
		Ext.apply(this, config);
		Ext.list.ColumnResizer.superclass.constructor.call(this);
	},
	init : function(listView){
		this.view = listView;
		listView.on('render', this.initEvents, this);
	},

	initEvents : function(view){
		view.mon(view.innerHd, 'mousemove', this.handleHdMove, this);
		this.tracker = new Ext.dd.DragTracker({
			onBeforeStart: this.onBeforeStart.createDelegate(this),
			onStart: this.onStart.createDelegate(this),
			onDrag: this.onDrag.createDelegate(this),
			onEnd: this.onEnd.createDelegate(this),
			tolerance: 3,
			autoStart: 300
		});
		this.tracker.initEl(view.innerHd);
		view.on('beforedestroy', this.tracker.destroy, this.tracker);
	},

	handleHdMove : function(e, t){
		var handleWidth = 5,
		x = e.getPageX(),
		header = e.getTarget('em', 3, true);
		if(header){
			var region = header.getRegion(),
			style = header.dom.style,
			parentNode = header.dom.parentNode;

			if(x - region.left <= handleWidth && parentNode != parentNode.parentNode.firstChild){
				this.activeHd = Ext.get(parentNode.previousSibling.firstChild);
				style.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize';
			} else if(region.right - x <= handleWidth && parentNode != parentNode.parentNode.lastChild.previousSibling){
				this.activeHd = header;
				style.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize';
			} else{
				delete this.activeHd;
				style.cursor = '';
			}
		}
	},

	onBeforeStart : function(e){
		this.dragHd = this.activeHd;
		return !!this.dragHd;
	},

	onStart: function(e){

		var me = this,
		view = me.view,
		dragHeader = me.dragHd,
		x = me.tracker.getXY()[0];

		me.proxy = view.el.createChild({
			cls:'x-list-resizer'
		});
		me.dragX = dragHeader.getX();
		me.headerIndex = view.findHeaderIndex(dragHeader);

		me.headersDisabled = view.disableHeaders;
		view.disableHeaders = true;

		me.proxy.setHeight(view.el.getHeight());
		me.proxy.setX(me.dragX);
		me.proxy.setWidth(x - me.dragX);

		this.setBoundaries();

	},


	setBoundaries: function(relativeX){
		var view = this.view,
		headerIndex = this.headerIndex,
		width = view.innerHd.getWidth(),
		relativeX = view.innerHd.getX(),
		minWidth = Math.ceil(width * this.minPct),
		maxWidth = width - minWidth,
		numColumns = view.columns.length,
		headers = view.innerHd.select('em', true),
		minX = minWidth + relativeX,
		maxX = maxWidth + relativeX,
		header;

		if (numColumns == 2) {
			this.minX = minX;
			this.maxX = maxX;
		}else{
			header = headers.item(headerIndex + 2);
			this.minX = headers.item(headerIndex).getX() + minWidth;
			this.maxX = header ? header.getX() - minWidth : maxX;
			if (headerIndex == 0) {

				this.minX = minX;
			} else if (headerIndex == numColumns - 2) {

				this.maxX = maxX;
			}
		}
	},

	onDrag: function(e){
		var me = this,
		cursorX = me.tracker.getXY()[0].constrain(me.minX, me.maxX);

		me.proxy.setWidth(cursorX - this.dragX);
	},

	onEnd: function(e){

		var newWidth = this.proxy.getWidth(),
		index = this.headerIndex,
		view = this.view,
		columns = view.columns,
		width = view.innerHd.getWidth(),
		newPercent = Math.ceil(newWidth * view.maxColumnWidth / width) / 100,
		disabled = this.headersDisabled,
		headerCol = columns[index],
		otherCol = columns[index + 1],
		totalPercent = headerCol.width + otherCol.width;

		this.proxy.remove();

		headerCol.width = newPercent;
		otherCol.width = totalPercent - newPercent;

		delete this.dragHd;
		view.setHdWidths();
		view.refresh();

		setTimeout(function(){
			view.disableHeaders = disabled;
		}, 100);
	}
});


Ext.ListView.ColumnResizer = Ext.list.ColumnResizer;
Ext.list.Sorter = Ext.extend(Ext.util.Observable, {

	sortClasses : ["sort-asc", "sort-desc"],

	constructor: function(config){
		Ext.apply(this, config);
		Ext.list.Sorter.superclass.constructor.call(this);
	},

	init : function(listView){
		this.view = listView;
		listView.on('render', this.initEvents, this);
	},

	initEvents : function(view){
		view.mon(view.innerHd, 'click', this.onHdClick, this);
		view.innerHd.setStyle('cursor', 'pointer');
		view.mon(view.store, 'datachanged', this.updateSortState, this);
		this.updateSortState.defer(10, this, [view.store]);
	},

	updateSortState : function(store){
		var state = store.getSortState();
		if(!state){
			return;
		}
		this.sortState = state;
		var cs = this.view.columns, sortColumn = -1;
		for(var i = 0, len = cs.length; i < len; i++){
			if(cs[i].dataIndex == state.field){
				sortColumn = i;
				break;
			}
		}
		if(sortColumn != -1){
			var sortDir = state.direction;
			this.updateSortIcon(sortColumn, sortDir);
		}
	},

	updateSortIcon : function(col, dir){
		var sc = this.sortClasses;
		var hds = this.view.innerHd.select('em').removeClass(sc);
		hds.item(col).addClass(sc[dir == "DESC" ? 1 : 0]);
	},

	onHdClick : function(e){
		var hd = e.getTarget('em', 3);
		if(hd && !this.view.disableHeaders){
			var index = this.view.findHeaderIndex(hd);
			this.view.store.sort(this.view.columns[index].dataIndex);
		}
	}
});


Ext.ListView.Sorter = Ext.list.Sorter;
Ext.TabPanel = Ext.extend(Ext.Panel,  {



	deferredRender : true,

	tabWidth : 120,

	minTabWidth : 30,

	resizeTabs : false,

	enableTabScroll : false,

	scrollIncrement : 0,

	scrollRepeatInterval : 400,

	scrollDuration : 0.35,

	animScroll : true,

	tabPosition : 'top',

	baseCls : 'x-tab-panel',

	autoTabs : false,

	autoTabSelector : 'div.x-tab',

	activeTab : undefined,

	tabMargin : 2,

	plain : false,

	wheelIncrement : 20,


	idDelimiter : '__',


	itemCls : 'x-tab-item',


	elements : 'body',
	headerAsText : false,
	frame : false,
	hideBorders :true,


	initComponent : function(){
		this.frame = false;
		Ext.TabPanel.superclass.initComponent.call(this);
		this.addEvents(

			'beforetabchange',

			'tabchange',

			'contextmenu'
			);

		this.setLayout(new Ext.layout.CardLayout(Ext.apply({
			layoutOnCardChange: this.layoutOnTabChange,
			deferredRender: this.deferredRender
		}, this.layoutConfig)));

		if(this.tabPosition == 'top'){
			this.elements += ',header';
			this.stripTarget = 'header';
		}else {
			this.elements += ',footer';
			this.stripTarget = 'footer';
		}
		if(!this.stack){
			this.stack = Ext.TabPanel.AccessStack();
		}
		this.initItems();
	},


	onRender : function(ct, position){
		Ext.TabPanel.superclass.onRender.call(this, ct, position);

		if(this.plain){
			var pos = this.tabPosition == 'top' ? 'header' : 'footer';
			this[pos].addClass('x-tab-panel-'+pos+'-plain');
		}

		var st = this[this.stripTarget];

		this.stripWrap = st.createChild({
			cls:'x-tab-strip-wrap',
			cn:{
				tag:'ul',
				cls:'x-tab-strip x-tab-strip-'+this.tabPosition
				}
			});

	var beforeEl = (this.tabPosition=='bottom' ? this.stripWrap : null);
	st.createChild({
		cls:'x-tab-strip-spacer'
	}, beforeEl);
	this.strip = new Ext.Element(this.stripWrap.dom.firstChild);


	this.edge = this.strip.createChild({
		tag:'li',
		cls:'x-tab-edge',
		cn: [{
			tag: 'span',
			cls: 'x-tab-strip-text',
			cn: '&#160;'
		}]
		});
	this.strip.createChild({
		cls:'x-clear'
	});

	this.body.addClass('x-tab-panel-body-'+this.tabPosition);


	if(!this.itemTpl){
		var tt = new Ext.Template(
			'<li class="{cls}" id="{id}"><a class="x-tab-strip-close"></a>',
			'<a class="x-tab-right" href="#"><em class="x-tab-left">',
			'<span class="x-tab-strip-inner"><span class="x-tab-strip-text {iconCls}">{text}</span></span>',
			'</em></a></li>'
			);
		tt.disableFormats = true;
		tt.compile();
		Ext.TabPanel.prototype.itemTpl = tt;
	}

	this.items.each(this.initTab, this);
},


afterRender : function(){
	Ext.TabPanel.superclass.afterRender.call(this);
	if(this.autoTabs){
		this.readTabs(false);
	}
	if(this.activeTab !== undefined){
		var item = Ext.isObject(this.activeTab) ? this.activeTab : this.items.get(this.activeTab);
		delete this.activeTab;
		this.setActiveTab(item);
	}
},


initEvents : function(){
	Ext.TabPanel.superclass.initEvents.call(this);
	this.mon(this.strip, {
		scope: this,
		mousedown: this.onStripMouseDown,
		contextmenu: this.onStripContextMenu
	});
	if(this.enableTabScroll){
		this.mon(this.strip, 'mousewheel', this.onWheel, this);
	}
},


findTargets : function(e){
	var item = null,
	itemEl = e.getTarget('li:not(.x-tab-edge)', this.strip);

	if(itemEl){
		item = this.getComponent(itemEl.id.split(this.idDelimiter)[1]);
		if(item.disabled){
			return {
				close : null,
				item : null,
				el : null
			};
		}
	}
	return {
		close : e.getTarget('.x-tab-strip-close', this.strip),
		item : item,
		el : itemEl
	};
},


onStripMouseDown : function(e){
	if(e.button !== 0){
		return;
	}
	e.preventDefault();
	var t = this.findTargets(e);
	if(t.close){
		if (t.item.fireEvent('beforeclose', t.item) !== false) {
			t.item.fireEvent('close', t.item);
			this.remove(t.item);
		}
		return;
	}
	if(t.item && t.item != this.activeTab){
		this.setActiveTab(t.item);
	}
},


onStripContextMenu : function(e){
	e.preventDefault();
	var t = this.findTargets(e);
	if(t.item){
		this.fireEvent('contextmenu', this, t.item, e);
	}
},


readTabs : function(removeExisting){
	if(removeExisting === true){
		this.items.each(function(item){
			this.remove(item);
		}, this);
	}
	var tabs = this.el.query(this.autoTabSelector);
	for(var i = 0, len = tabs.length; i < len; i++){
		var tab = tabs[i],
		title = tab.getAttribute('title');
		tab.removeAttribute('title');
		this.add({
			title: title,
			contentEl: tab
		});
	}
},


initTab : function(item, index){
	var before = this.strip.dom.childNodes[index],
	p = this.getTemplateArgs(item),
	el = before ?
	this.itemTpl.insertBefore(before, p) :
	this.itemTpl.append(this.strip, p),
	cls = 'x-tab-strip-over',
	tabEl = Ext.get(el);

	tabEl.hover(function(){
		if(!item.disabled){
			tabEl.addClass(cls);
		}
	}, function(){
		tabEl.removeClass(cls);
	});

	if(item.tabTip){
		tabEl.child('span.x-tab-strip-text', true).qtip = item.tabTip;
	}
	item.tabEl = el;


	tabEl.select('a').on('click', function(e){
		if(!e.getPageX()){
			this.onStripMouseDown(e);
		}
	}, this, {
		preventDefault: true
	});

	item.on({
		scope: this,
		disable: this.onItemDisabled,
		enable: this.onItemEnabled,
		titlechange: this.onItemTitleChanged,
		iconchange: this.onItemIconChanged,
		beforeshow: this.onBeforeShowItem
	});
},




getTemplateArgs : function(item) {
	var cls = item.closable ? 'x-tab-strip-closable' : '';
	if(item.disabled){
		cls += ' x-item-disabled';
	}
	if(item.iconCls){
		cls += ' x-tab-with-icon';
	}
	if(item.tabCls){
		cls += ' ' + item.tabCls;
	}

	return {
		id: this.id + this.idDelimiter + item.getItemId(),
		text: item.title,
		cls: cls,
		iconCls: item.iconCls || ''
	};
},


onAdd : function(c){
	Ext.TabPanel.superclass.onAdd.call(this, c);
	if(this.rendered){
		var items = this.items;
		this.initTab(c, items.indexOf(c));
		this.delegateUpdates();
	}
},


onBeforeAdd : function(item){
	var existing = item.events ? (this.items.containsKey(item.getItemId()) ? item : null) : this.items.get(item);
	if(existing){
		this.setActiveTab(item);
		return false;
	}
	Ext.TabPanel.superclass.onBeforeAdd.apply(this, arguments);
	var es = item.elements;
	item.elements = es ? es.replace(',header', '') : es;
	item.border = (item.border === true);
},


onRemove : function(c){
	var te = Ext.get(c.tabEl);

	if(te){
		te.select('a').removeAllListeners();
		Ext.destroy(te);
	}
	Ext.TabPanel.superclass.onRemove.call(this, c);
	this.stack.remove(c);
	delete c.tabEl;
	c.un('disable', this.onItemDisabled, this);
	c.un('enable', this.onItemEnabled, this);
	c.un('titlechange', this.onItemTitleChanged, this);
	c.un('iconchange', this.onItemIconChanged, this);
	c.un('beforeshow', this.onBeforeShowItem, this);
	if(c == this.activeTab){
		var next = this.stack.next();
		if(next){
			this.setActiveTab(next);
		}else if(this.items.getCount() > 0){
			this.setActiveTab(0);
		}else{
			this.setActiveTab(null);
		}
	}
	if(!this.destroying){
		this.delegateUpdates();
	}
},


onBeforeShowItem : function(item){
	if(item != this.activeTab){
		this.setActiveTab(item);
		return false;
	}
},


onItemDisabled : function(item){
	var el = this.getTabEl(item);
	if(el){
		Ext.fly(el).addClass('x-item-disabled');
	}
	this.stack.remove(item);
},


onItemEnabled : function(item){
	var el = this.getTabEl(item);
	if(el){
		Ext.fly(el).removeClass('x-item-disabled');
	}
},


onItemTitleChanged : function(item){
	var el = this.getTabEl(item);
	if(el){
		Ext.fly(el).child('span.x-tab-strip-text', true).innerHTML = item.title;
	}
},


onItemIconChanged : function(item, iconCls, oldCls){
	var el = this.getTabEl(item);
	if(el){
		el = Ext.get(el);
		el.child('span.x-tab-strip-text').replaceClass(oldCls, iconCls);
		el[Ext.isEmpty(iconCls) ? 'removeClass' : 'addClass']('x-tab-with-icon');
	}
},


getTabEl : function(item){
	var c = this.getComponent(item);
	return c ? c.tabEl : null;
},


onResize : function(){
	Ext.TabPanel.superclass.onResize.apply(this, arguments);
	this.delegateUpdates();
},


beginUpdate : function(){
	this.suspendUpdates = true;
},


endUpdate : function(){
	this.suspendUpdates = false;
	this.delegateUpdates();
},


hideTabStripItem : function(item){
	item = this.getComponent(item);
	var el = this.getTabEl(item);
	if(el){
		el.style.display = 'none';
		this.delegateUpdates();
	}
	this.stack.remove(item);
},


unhideTabStripItem : function(item){
	item = this.getComponent(item);
	var el = this.getTabEl(item);
	if(el){
		el.style.display = '';
		this.delegateUpdates();
	}
},


delegateUpdates : function(){
	var rendered = this.rendered;
	if(this.suspendUpdates){
		return;
	}
	if(this.resizeTabs && rendered){
		this.autoSizeTabs();
	}
	if(this.enableTabScroll && rendered){
		this.autoScrollTabs();
	}
},


autoSizeTabs : function(){
	var count = this.items.length,
	ce = this.tabPosition != 'bottom' ? 'header' : 'footer',
	ow = this[ce].dom.offsetWidth,
	aw = this[ce].dom.clientWidth;

	if(!this.resizeTabs || count < 1 || !aw){
		return;
	}

	var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.tabMargin, this.tabWidth), this.minTabWidth);
	this.lastTabWidth = each;
	var lis = this.strip.query('li:not(.x-tab-edge)');
	for(var i = 0, len = lis.length; i < len; i++) {
		var li = lis[i],
		inner = Ext.fly(li).child('.x-tab-strip-inner', true),
		tw = li.offsetWidth,
		iw = inner.offsetWidth;
		inner.style.width = (each - (tw-iw)) + 'px';
	}
},


adjustBodyWidth : function(w){
	if(this.header){
		this.header.setWidth(w);
	}
	if(this.footer){
		this.footer.setWidth(w);
	}
	return w;
},


setActiveTab : function(item){
	item = this.getComponent(item);
	if(this.fireEvent('beforetabchange', this, item, this.activeTab) === false){
		return;
	}
	if(!this.rendered){
		this.activeTab = item;
		return;
	}
	if(this.activeTab != item){
		if(this.activeTab){
			var oldEl = this.getTabEl(this.activeTab);
			if(oldEl){
				Ext.fly(oldEl).removeClass('x-tab-strip-active');
			}
		}
		this.activeTab = item;
		if(item){
			var el = this.getTabEl(item);
			Ext.fly(el).addClass('x-tab-strip-active');
			this.stack.add(item);

			this.layout.setActiveItem(item);

			this.delegateUpdates();
			if(this.scrolling){
				this.scrollToTab(item, this.animScroll);
			}
		}
		this.fireEvent('tabchange', this, item);
	}
},


getActiveTab : function(){
	return this.activeTab || null;
},


getItem : function(item){
	return this.getComponent(item);
},


autoScrollTabs : function(){
	this.pos = this.tabPosition=='bottom' ? this.footer : this.header;
	var count = this.items.length,
	ow = this.pos.dom.offsetWidth,
	tw = this.pos.dom.clientWidth,
	wrap = this.stripWrap,
	wd = wrap.dom,
	cw = wd.offsetWidth,
	pos = this.getScrollPos(),
	l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;

	if(!this.enableTabScroll || cw < 20){
		return;
	}
	if(count == 0 || l <= tw){

		wd.scrollLeft = 0;
		wrap.setWidth(tw);
		if(this.scrolling){
			this.scrolling = false;
			this.pos.removeClass('x-tab-scrolling');
			this.scrollLeft.hide();
			this.scrollRight.hide();

			if(Ext.isAir || Ext.isWebKit){
				wd.style.marginLeft = '';
				wd.style.marginRight = '';
			}
		}
	}else{
		if(!this.scrolling){
			this.pos.addClass('x-tab-scrolling');

			if(Ext.isAir || Ext.isWebKit){
				wd.style.marginLeft = '18px';
				wd.style.marginRight = '18px';
			}
		}
		tw -= wrap.getMargins('lr');
		wrap.setWidth(tw > 20 ? tw : 20);
		if(!this.scrolling){
			if(!this.scrollLeft){
				this.createScrollers();
			}else{
				this.scrollLeft.show();
				this.scrollRight.show();
			}
		}
		this.scrolling = true;
		if(pos > (l-tw)){
			wd.scrollLeft = l-tw;
		}else{
			this.scrollToTab(this.activeTab, false);
		}
		this.updateScrollButtons();
	}
},


createScrollers : function(){
	this.pos.addClass('x-tab-scrolling-' + this.tabPosition);
	var h = this.stripWrap.dom.offsetHeight;


	var sl = this.pos.insertFirst({
		cls:'x-tab-scroller-left'
	});
	sl.setHeight(h);
	sl.addClassOnOver('x-tab-scroller-left-over');
	this.leftRepeater = new Ext.util.ClickRepeater(sl, {
		interval : this.scrollRepeatInterval,
		handler: this.onScrollLeft,
		scope: this
	});
	this.scrollLeft = sl;


	var sr = this.pos.insertFirst({
		cls:'x-tab-scroller-right'
	});
	sr.setHeight(h);
	sr.addClassOnOver('x-tab-scroller-right-over');
	this.rightRepeater = new Ext.util.ClickRepeater(sr, {
		interval : this.scrollRepeatInterval,
		handler: this.onScrollRight,
		scope: this
	});
	this.scrollRight = sr;
},


getScrollWidth : function(){
	return this.edge.getOffsetsTo(this.stripWrap)[0] + this.getScrollPos();
},


getScrollPos : function(){
	return parseInt(this.stripWrap.dom.scrollLeft, 10) || 0;
},


getScrollArea : function(){
	return parseInt(this.stripWrap.dom.clientWidth, 10) || 0;
},


getScrollAnim : function(){
	return {
		duration:this.scrollDuration,
		callback: this.updateScrollButtons,
		scope: this
	};
},


getScrollIncrement : function(){
	return this.scrollIncrement || (this.resizeTabs ? this.lastTabWidth+2 : 100);
},



scrollToTab : function(item, animate){
	if(!item){
		return;
	}
	var el = this.getTabEl(item),
	pos = this.getScrollPos(),
	area = this.getScrollArea(),
	left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos,
	right = left + el.offsetWidth;
	if(left < pos){
		this.scrollTo(left, animate);
	}else if(right > (pos + area)){
		this.scrollTo(right - area, animate);
	}
},


scrollTo : function(pos, animate){
	this.stripWrap.scrollTo('left', pos, animate ? this.getScrollAnim() : false);
	if(!animate){
		this.updateScrollButtons();
	}
},

onWheel : function(e){
	var d = e.getWheelDelta()*this.wheelIncrement*-1;
	e.stopEvent();

	var pos = this.getScrollPos(),
	newpos = pos + d,
	sw = this.getScrollWidth()-this.getScrollArea();

	var s = Math.max(0, Math.min(sw, newpos));
	if(s != pos){
		this.scrollTo(s, false);
	}
},


onScrollRight : function(){
	var sw = this.getScrollWidth()-this.getScrollArea(),
	pos = this.getScrollPos(),
	s = Math.min(sw, pos + this.getScrollIncrement());
	if(s != pos){
		this.scrollTo(s, this.animScroll);
	}
},


onScrollLeft : function(){
	var pos = this.getScrollPos(),
	s = Math.max(0, pos - this.getScrollIncrement());
	if(s != pos){
		this.scrollTo(s, this.animScroll);
	}
},


updateScrollButtons : function(){
	var pos = this.getScrollPos();
	this.scrollLeft[pos === 0 ? 'addClass' : 'removeClass']('x-tab-scroller-left-disabled');
	this.scrollRight[pos >= (this.getScrollWidth()-this.getScrollArea()) ? 'addClass' : 'removeClass']('x-tab-scroller-right-disabled');
},


beforeDestroy : function() {
	Ext.destroy(this.leftRepeater, this.rightRepeater);
	this.deleteMembers('strip', 'edge', 'scrollLeft', 'scrollRight', 'stripWrap');
	this.activeTab = null;
	Ext.TabPanel.superclass.beforeDestroy.apply(this);
}













});
Ext.reg('tabpanel', Ext.TabPanel);


Ext.TabPanel.prototype.activate = Ext.TabPanel.prototype.setActiveTab;


Ext.TabPanel.AccessStack = function(){
	var items = [];
	return {
		add : function(item){
			items.push(item);
			if(items.length > 10){
				items.shift();
			}
		},

		remove : function(item){
			var s = [];
			for(var i = 0, len = items.length; i < len; i++) {
				if(items[i] != item){
					s.push(items[i]);
				}
			}
			items = s;
		},

		next : function(){
			return items.pop();
		}
	};
};

Ext.Button = Ext.extend(Ext.BoxComponent, {

	hidden : false,

	disabled : false,

	pressed : false,






	enableToggle : false,



	menuAlign : 'tl-bl?',




	type : 'button',


	menuClassTarget : 'tr:nth(2)',


	clickEvent : 'click',


	handleMouseEvents : true,


	tooltipType : 'qtip',


	buttonSelector : 'button:first-child',


	scale : 'small',




	iconAlign : 'left',


	arrowAlign : 'right',






	initComponent : function(){
		if(this.menu){
			this.menu = Ext.menu.MenuMgr.get(this.menu);
			this.menu.ownerCt = this;
		}

		Ext.Button.superclass.initComponent.call(this);

		this.addEvents(

			'click',

			'toggle',

			'mouseover',

			'mouseout',

			'menushow',

			'menuhide',

			'menutriggerover',

			'menutriggerout'
			);

		if (this.menu){
			this.menu.ownerCt = undefined;
		}
		if(Ext.isString(this.toggleGroup)){
			this.enableToggle = true;
		}
	},


	getTemplateArgs : function(){
		return [this.type, 'x-btn-' + this.scale + ' x-btn-icon-' + this.scale + '-' + this.iconAlign, this.getMenuClass(), this.cls, this.id];
	},


	setButtonClass : function(){
		if(this.useSetClass){
			if(!Ext.isEmpty(this.oldCls)){
				this.el.removeClass([this.oldCls, 'x-btn-pressed']);
			}
			this.oldCls = (this.iconCls || this.icon) ? (this.text ? 'x-btn-text-icon' : 'x-btn-icon') : 'x-btn-noicon';
			this.el.addClass([this.oldCls, this.pressed ? 'x-btn-pressed' : null]);
		}
	},


	getMenuClass : function(){
		return this.menu ? (this.arrowAlign != 'bottom' ? 'x-btn-arrow' : 'x-btn-arrow-bottom') : '';
	},


	onRender : function(ct, position){
		if(!this.template){
			if(!Ext.Button.buttonTemplate){

				Ext.Button.buttonTemplate = new Ext.Template(
					'<table id="{4}" cellspacing="0" class="x-btn {3}"><tbody class="{1}">',
					'<tr><td class="x-btn-tl"><i>&#160;</i></td><td class="x-btn-tc"></td><td class="x-btn-tr"><i>&#160;</i></td></tr>',
					'<tr><td class="x-btn-ml"><i>&#160;</i></td><td class="x-btn-mc"><em class="{2}" unselectable="on"><button type="{0}"></button></em></td><td class="x-btn-mr"><i>&#160;</i></td></tr>',
					'<tr><td class="x-btn-bl"><i>&#160;</i></td><td class="x-btn-bc"></td><td class="x-btn-br"><i>&#160;</i></td></tr>',
					'</tbody></table>');
				Ext.Button.buttonTemplate.compile();
			}
			this.template = Ext.Button.buttonTemplate;
		}

		var btn, targs = this.getTemplateArgs();

		if(position){
			btn = this.template.insertBefore(position, targs, true);
		}else{
			btn = this.template.append(ct, targs, true);
		}

		this.btnEl = btn.child(this.buttonSelector);
		this.mon(this.btnEl, {
			scope: this,
			focus: this.onFocus,
			blur: this.onBlur
		});

		this.initButtonEl(btn, this.btnEl);

		Ext.ButtonToggleMgr.register(this);
	},


	initButtonEl : function(btn, btnEl){
		this.el = btn;
		this.setIcon(this.icon);
		this.setText(this.text);
		this.setIconClass(this.iconCls);
		if(Ext.isDefined(this.tabIndex)){
			btnEl.dom.tabIndex = this.tabIndex;
		}
		if(this.tooltip){
			this.setTooltip(this.tooltip, true);
		}

		if(this.handleMouseEvents){
			this.mon(btn, {
				scope: this,
				mouseover: this.onMouseOver,
				mousedown: this.onMouseDown
			});



		}

		if(this.menu){
			this.mon(this.menu, {
				scope: this,
				show: this.onMenuShow,
				hide: this.onMenuHide
			});
		}

		if(this.repeat){
			var repeater = new Ext.util.ClickRepeater(btn, Ext.isObject(this.repeat) ? this.repeat : {});
			this.mon(repeater, 'click', this.onRepeatClick, this);
		}else{
			this.mon(btn, this.clickEvent, this.onClick, this);
		}
	},


	afterRender : function(){
		Ext.Button.superclass.afterRender.call(this);
		this.useSetClass = true;
		this.setButtonClass();
		this.doc = Ext.getDoc();
		this.doAutoWidth();
	},


	setIconClass : function(cls){
		this.iconCls = cls;
		if(this.el){
			this.btnEl.dom.className = '';
			this.btnEl.addClass(['x-btn-text', cls || '']);
			this.setButtonClass();
		}
		return this;
	},


	setTooltip : function(tooltip,  initial){
		if(this.rendered){
			if(!initial){
				this.clearTip();
			}
			if(Ext.isObject(tooltip)){
				Ext.QuickTips.register(Ext.apply({
					target: this.btnEl.id
				}, tooltip));
				this.tooltip = tooltip;
			}else{
				this.btnEl.dom[this.tooltipType] = tooltip;
			}
		}else{
			this.tooltip = tooltip;
		}
		return this;
	},


	clearTip : function(){
		if(Ext.isObject(this.tooltip)){
			Ext.QuickTips.unregister(this.btnEl);
		}
	},


	beforeDestroy : function(){
		if(this.rendered){
			this.clearTip();
		}
		if(this.menu && this.destroyMenu !== false) {
			Ext.destroy(this.btnEl, this.menu);
		}
		Ext.destroy(this.repeater);
	},


	onDestroy : function(){
		if(this.rendered){
			this.doc.un('mouseover', this.monitorMouseOver, this);
			this.doc.un('mouseup', this.onMouseUp, this);
			delete this.doc;
			delete this.btnEl;
			Ext.ButtonToggleMgr.unregister(this);
		}
		Ext.Button.superclass.onDestroy.call(this);
	},


	doAutoWidth : function(){
		if(this.autoWidth !== false && this.el && this.text && this.width === undefined){
			this.el.setWidth('auto');
			if(Ext.isIE7 && Ext.isStrict){
				var ib = this.btnEl;
				if(ib && ib.getWidth() > 20){
					ib.clip();
					ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr'));
				}
			}
			if(this.minWidth){
				if(this.el.getWidth() < this.minWidth){
					this.el.setWidth(this.minWidth);
				}
			}
		}
	},


	setHandler : function(handler, scope){
		this.handler = handler;
		this.scope = scope;
		return this;
	},


	setText : function(text){
		this.text = text;
		if(this.el){
			this.btnEl.update(text || '&#160;');
			this.setButtonClass();
		}
		this.doAutoWidth();
		return this;
	},


	setIcon : function(icon){
		this.icon = icon;
		if(this.el){
			this.btnEl.setStyle('background-image', icon ? 'url(' + icon + ')' : '');
			this.setButtonClass();
		}
		return this;
	},


	getText : function(){
		return this.text;
	},


	toggle : function(state, suppressEvent){
		state = state === undefined ? !this.pressed : !!state;
		if(state != this.pressed){
			if(this.rendered){
				this.el[state ? 'addClass' : 'removeClass']('x-btn-pressed');
			}
			this.pressed = state;
			if(!suppressEvent){
				this.fireEvent('toggle', this, state);
				if(this.toggleHandler){
					this.toggleHandler.call(this.scope || this, this, state);
				}
			}
		}
		return this;
	},


	onDisable : function(){
		this.onDisableChange(true);
	},


	onEnable : function(){
		this.onDisableChange(false);
	},

	onDisableChange : function(disabled){
		if(this.el){
			if(!Ext.isIE6 || !this.text){
				this.el[disabled ? 'addClass' : 'removeClass'](this.disabledClass);
			}
			this.el.dom.disabled = disabled;
		}
		this.disabled = disabled;
	},


	showMenu : function(){
		if(this.rendered && this.menu){
			if(this.tooltip){
				Ext.QuickTips.getQuickTip().cancelShow(this.btnEl);
			}
			if(this.menu.isVisible()){
				this.menu.hide();
			}
			this.menu.ownerCt = this;
			this.menu.show(this.el, this.menuAlign);
		}
		return this;
	},


	hideMenu : function(){
		if(this.hasVisibleMenu()){
			this.menu.hide();
		}
		return this;
	},


	hasVisibleMenu : function(){
		return this.menu && this.menu.ownerCt == this && this.menu.isVisible();
	},


	onRepeatClick : function(repeat, e){
		this.onClick(e);
	},


	onClick : function(e){
		if(e){
			e.preventDefault();
		}
		if(e.button !== 0){
			return;
		}
		if(!this.disabled){
			this.doToggle();
			if(this.menu && !this.hasVisibleMenu() && !this.ignoreNextClick){
				this.showMenu();
			}
			this.fireEvent('click', this, e);
			if(this.handler){

				this.handler.call(this.scope || this, this, e);
			}
		}
	},


	doToggle: function(){
		if (this.enableToggle && (this.allowDepress !== false || !this.pressed)) {
			this.toggle();
		}
	},


	isMenuTriggerOver : function(e, internal){
		return this.menu && !internal;
	},


	isMenuTriggerOut : function(e, internal){
		return this.menu && !internal;
	},


	onMouseOver : function(e){
		if(!this.disabled){
			var internal = e.within(this.el,  true);
			if(!internal){
				this.el.addClass('x-btn-over');
				if(!this.monitoringMouseOver){
					this.doc.on('mouseover', this.monitorMouseOver, this);
					this.monitoringMouseOver = true;
				}
				this.fireEvent('mouseover', this, e);
			}
			if(this.isMenuTriggerOver(e, internal)){
				this.fireEvent('menutriggerover', this, this.menu, e);
			}
		}
	},


	monitorMouseOver : function(e){
		if(e.target != this.el.dom && !e.within(this.el)){
			if(this.monitoringMouseOver){
				this.doc.un('mouseover', this.monitorMouseOver, this);
				this.monitoringMouseOver = false;
			}
			this.onMouseOut(e);
		}
	},


	onMouseOut : function(e){
		var internal = e.within(this.el) && e.target != this.el.dom;
		this.el.removeClass('x-btn-over');
		this.fireEvent('mouseout', this, e);
		if(this.isMenuTriggerOut(e, internal)){
			this.fireEvent('menutriggerout', this, this.menu, e);
		}
	},

	focus : function() {
		this.btnEl.focus();
	},

	blur : function() {
		this.btnEl.blur();
	},


	onFocus : function(e){
		if(!this.disabled){
			this.el.addClass('x-btn-focus');
		}
	},

	onBlur : function(e){
		this.el.removeClass('x-btn-focus');
	},


	getClickEl : function(e, isUp){
		return this.el;
	},


	onMouseDown : function(e){
		if(!this.disabled && e.button === 0){
			this.getClickEl(e).addClass('x-btn-click');
			this.doc.on('mouseup', this.onMouseUp, this);
		}
	},

	onMouseUp : function(e){
		if(e.button === 0){
			this.getClickEl(e, true).removeClass('x-btn-click');
			this.doc.un('mouseup', this.onMouseUp, this);
		}
	},

	onMenuShow : function(e){
		if(this.menu.ownerCt == this){
			this.menu.ownerCt = this;
			this.ignoreNextClick = 0;
			this.el.addClass('x-btn-menu-active');
			this.fireEvent('menushow', this, this.menu);
		}
	},

	onMenuHide : function(e){
		if(this.menu.ownerCt == this){
			this.el.removeClass('x-btn-menu-active');
			this.ignoreNextClick = this.restoreClick.defer(250, this);
			this.fireEvent('menuhide', this, this.menu);
			delete this.menu.ownerCt;
		}
	},


	restoreClick : function(){
		this.ignoreNextClick = 0;
	}







});
Ext.reg('button', Ext.Button);


Ext.ButtonToggleMgr = function(){
	var groups = {};

	function toggleGroup(btn, state){
		if(state){
			var g = groups[btn.toggleGroup];
			for(var i = 0, l = g.length; i < l; i++){
				if(g[i] != btn){
					g[i].toggle(false);
				}
			}
		}
	}

	return {
		register : function(btn){
			if(!btn.toggleGroup){
				return;
			}
			var g = groups[btn.toggleGroup];
			if(!g){
				g = groups[btn.toggleGroup] = [];
			}
			g.push(btn);
			btn.on('toggle', toggleGroup);
		},

		unregister : function(btn){
			if(!btn.toggleGroup){
				return;
			}
			var g = groups[btn.toggleGroup];
			if(g){
				g.remove(btn);
				btn.un('toggle', toggleGroup);
			}
		},


		getPressed : function(group){
			var g = groups[group];
			if(g){
				for(var i = 0, len = g.length; i < len; i++){
					if(g[i].pressed === true){
						return g[i];
					}
				}
			}
			return null;
		}
	};
}();

Ext.SplitButton = Ext.extend(Ext.Button, {

	arrowSelector : 'em',
	split: true,


	initComponent : function(){
		Ext.SplitButton.superclass.initComponent.call(this);

		this.addEvents("arrowclick");
	},


	onRender : function(){
		Ext.SplitButton.superclass.onRender.apply(this, arguments);
		if(this.arrowTooltip){
			this.el.child(this.arrowSelector).dom[this.tooltipType] = this.arrowTooltip;
		}
	},


	setArrowHandler : function(handler, scope){
		this.arrowHandler = handler;
		this.scope = scope;
	},

	getMenuClass : function(){
		return 'x-btn-split' + (this.arrowAlign == 'bottom' ? '-bottom' : '');
	},

	isClickOnArrow : function(e){
		if (this.arrowAlign != 'bottom') {
			var visBtn = this.el.child('em.x-btn-split');
			var right = visBtn.getRegion().right - visBtn.getPadding('r');
			return e.getPageX() > right;
		} else {
			return e.getPageY() > this.btnEl.getRegion().bottom;
		}
	},


	onClick : function(e, t){
		e.preventDefault();
		if(!this.disabled){
			if(this.isClickOnArrow(e)){
				if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
					this.showMenu();
				}
				this.fireEvent("arrowclick", this, e);
				if(this.arrowHandler){
					this.arrowHandler.call(this.scope || this, this, e);
				}
			}else{
				this.doToggle();
				this.fireEvent("click", this, e);
				if(this.handler){
					this.handler.call(this.scope || this, this, e);
				}
			}
		}
	},


	isMenuTriggerOver : function(e){
		return this.menu && e.target.tagName == this.arrowSelector;
	},


	isMenuTriggerOut : function(e, internal){
		return this.menu && e.target.tagName != this.arrowSelector;
	}
});

Ext.reg('splitbutton', Ext.SplitButton);
Ext.CycleButton = Ext.extend(Ext.SplitButton, {








	getItemText : function(item){
		if(item && this.showText === true){
			var text = '';
			if(this.prependText){
				text += this.prependText;
			}
			text += item.text;
			return text;
		}
		return undefined;
	},


	setActiveItem : function(item, suppressEvent){
		if(!Ext.isObject(item)){
			item = this.menu.getComponent(item);
		}
		if(item){
			if(!this.rendered){
				this.text = this.getItemText(item);
				this.iconCls = item.iconCls;
			}else{
				var t = this.getItemText(item);
				if(t){
					this.setText(t);
				}
				this.setIconClass(item.iconCls);
			}
			this.activeItem = item;
			if(!item.checked){
				item.setChecked(true, false);
			}
			if(this.forceIcon){
				this.setIconClass(this.forceIcon);
			}
			if(!suppressEvent){
				this.fireEvent('change', this, item);
			}
		}
	},


	getActiveItem : function(){
		return this.activeItem;
	},


	initComponent : function(){
		this.addEvents(

			"change"
			);

		if(this.changeHandler){
			this.on('change', this.changeHandler, this.scope||this);
			delete this.changeHandler;
		}

		this.itemCount = this.items.length;

		this.menu = {
			cls:'x-cycle-menu',
			items:[]
		};
		var checked = 0;
		Ext.each(this.items, function(item, i){
			Ext.apply(item, {
				group: item.group || this.id,
				itemIndex: i,
				checkHandler: this.checkHandler,
				scope: this,
				checked: item.checked || false
			});
			this.menu.items.push(item);
			if(item.checked){
				checked = i;
			}
		}, this);
		Ext.CycleButton.superclass.initComponent.call(this);
		this.on('click', this.toggleSelected, this);
		this.setActiveItem(checked, true);
	},


	checkHandler : function(item, pressed){
		if(pressed){
			this.setActiveItem(item);
		}
	},


	toggleSelected : function(){
		var m = this.menu;
		m.render();

		if(!m.hasLayout){
			m.doLayout();
		}

		var nextIdx, checkItem;
		for (var i = 1; i < this.itemCount; i++) {
			nextIdx = (this.activeItem.itemIndex + i) % this.itemCount;

			checkItem = m.items.itemAt(nextIdx);

			if (!checkItem.disabled) {
				checkItem.setChecked(true);
				break;
			}
		}
	}
});
Ext.reg('cycle', Ext.CycleButton);
Ext.Toolbar = function(config){
	if(Ext.isArray(config)){
		config = {
			items: config,
			layout: 'toolbar'
		};
	} else {
		config = Ext.apply({
			layout: 'toolbar'
		}, config);
		if(config.buttons) {
			config.items = config.buttons;
		}
	}
	Ext.Toolbar.superclass.constructor.call(this, config);
};

(function(){

	var T = Ext.Toolbar;

	Ext.extend(T, Ext.Container, {

		defaultType: 'button',



		enableOverflow : false,




		trackMenus : true,
		internalDefaults: {
			removeMode: 'container',
			hideParent: true
		},
		toolbarCls: 'x-toolbar',

		initComponent : function(){
			T.superclass.initComponent.call(this);


			this.addEvents('overflowchange');
		},


		onRender : function(ct, position){
			if(!this.el){
				if(!this.autoCreate){
					this.autoCreate = {
						cls: this.toolbarCls + ' x-small-editor'
					};
				}
				this.el = ct.createChild(Ext.apply({
					id: this.id
				},this.autoCreate), position);
				Ext.Toolbar.superclass.onRender.apply(this, arguments);
			}
		},




		lookupComponent : function(c){
			if(Ext.isString(c)){
				if(c == '-'){
					c = new T.Separator();
				}else if(c == ' '){
					c = new T.Spacer();
				}else if(c == '->'){
					c = new T.Fill();
				}else{
					c = new T.TextItem(c);
				}
				this.applyDefaults(c);
			}else{
				if(c.isFormField || c.render){
					c = this.createComponent(c);
				}else if(c.tag){
					c = new T.Item({
						autoEl: c
					});
				}else if(c.tagName){
					c = new T.Item({
						el:c
					});
				}else if(Ext.isObject(c)){
					c = c.xtype ? this.createComponent(c) : this.constructButton(c);
				}
			}
			return c;
		},


		applyDefaults : function(c){
			if(!Ext.isString(c)){
				c = Ext.Toolbar.superclass.applyDefaults.call(this, c);
				var d = this.internalDefaults;
				if(c.events){
					Ext.applyIf(c.initialConfig, d);
					Ext.apply(c, d);
				}else{
					Ext.applyIf(c, d);
				}
			}
			return c;
		},


		addSeparator : function(){
			return this.add(new T.Separator());
		},


		addSpacer : function(){
			return this.add(new T.Spacer());
		},


		addFill : function(){
			this.add(new T.Fill());
		},


		addElement : function(el){
			return this.addItem(new T.Item({
				el:el
			}));
		},


		addItem : function(item){
			return this.add.apply(this, arguments);
		},


		addButton : function(config){
			if(Ext.isArray(config)){
				var buttons = [];
				for(var i = 0, len = config.length; i < len; i++) {
					buttons.push(this.addButton(config[i]));
				}
				return buttons;
			}
			return this.add(this.constructButton(config));
		},


		addText : function(text){
			return this.addItem(new T.TextItem(text));
		},


		addDom : function(config){
			return this.add(new T.Item({
				autoEl: config
			}));
		},


		addField : function(field){
			return this.add(field);
		},


		insertButton : function(index, item){
			if(Ext.isArray(item)){
				var buttons = [];
				for(var i = 0, len = item.length; i < len; i++) {
					buttons.push(this.insertButton(index + i, item[i]));
				}
				return buttons;
			}
			return Ext.Toolbar.superclass.insert.call(this, index, item);
		},


		trackMenu : function(item, remove){
			if(this.trackMenus && item.menu){
				var method = remove ? 'mun' : 'mon';
				this[method](item, 'menutriggerover', this.onButtonTriggerOver, this);
				this[method](item, 'menushow', this.onButtonMenuShow, this);
				this[method](item, 'menuhide', this.onButtonMenuHide, this);
			}
		},


		constructButton : function(item){
			var b = item.events ? item : this.createComponent(item, item.split ? 'splitbutton' : this.defaultType);
			return b;
		},


		onAdd : function(c){
			Ext.Toolbar.superclass.onAdd.call(this);
			this.trackMenu(c);
			if(this.disabled){
				c.disable();
			}
		},


		onRemove : function(c){
			Ext.Toolbar.superclass.onRemove.call(this);
			if (c == this.activeMenuBtn) {
				delete this.activeMenuBtn;
			}
			this.trackMenu(c, true);
		},


		onDisable : function(){
			this.items.each(function(item){
				if(item.disable){
					item.disable();
				}
			});
		},


		onEnable : function(){
			this.items.each(function(item){
				if(item.enable){
					item.enable();
				}
			});
		},


		onButtonTriggerOver : function(btn){
			if(this.activeMenuBtn && this.activeMenuBtn != btn){
				this.activeMenuBtn.hideMenu();
				btn.showMenu();
				this.activeMenuBtn = btn;
			}
		},


		onButtonMenuShow : function(btn){
			this.activeMenuBtn = btn;
		},


		onButtonMenuHide : function(btn){
			delete this.activeMenuBtn;
		}
	});
	Ext.reg('toolbar', Ext.Toolbar);


	T.Item = Ext.extend(Ext.BoxComponent, {
		hideParent: true,
		enable:Ext.emptyFn,
		disable:Ext.emptyFn,
		focus:Ext.emptyFn

	});
	Ext.reg('tbitem', T.Item);


	T.Separator = Ext.extend(T.Item, {
		onRender : function(ct, position){
			this.el = ct.createChild({
				tag:'span',
				cls:'xtb-sep'
			}, position);
		}
	});
	Ext.reg('tbseparator', T.Separator);


	T.Spacer = Ext.extend(T.Item, {


		onRender : function(ct, position){
			this.el = ct.createChild({
				tag:'div',
				cls:'xtb-spacer',
				style: this.width?'width:'+this.width+'px':''
				}, position);
		}
	});
	Ext.reg('tbspacer', T.Spacer);


	T.Fill = Ext.extend(T.Item, {

		render : Ext.emptyFn,
		isFill : true
	});
	Ext.reg('tbfill', T.Fill);


	T.TextItem = Ext.extend(T.Item, {


		constructor: function(config){
			T.TextItem.superclass.constructor.call(this, Ext.isString(config) ? {
				text: config
			} : config);
		},


		onRender : function(ct, position) {
			this.autoEl = {
				cls: 'xtb-text',
				html: this.text || ''
				};
			T.TextItem.superclass.onRender.call(this, ct, position);
		},


		setText : function(t) {
			if(this.rendered){
				this.el.update(t);
			}else{
				this.text = t;
			}
		}
	});
	Ext.reg('tbtext', T.TextItem);


	T.Button = Ext.extend(Ext.Button, {});
	T.SplitButton = Ext.extend(Ext.SplitButton, {});
	Ext.reg('tbbutton', T.Button);
	Ext.reg('tbsplit', T.SplitButton);

})();

Ext.ButtonGroup = Ext.extend(Ext.Panel, {


	baseCls: 'x-btn-group',

	layout:'table',
	defaultType: 'button',

	frame: true,
	internalDefaults: {
		removeMode: 'container',
		hideParent: true
	},

	initComponent : function(){
		this.layoutConfig = this.layoutConfig || {};
		Ext.applyIf(this.layoutConfig, {
			columns : this.columns
		});
		if(!this.title){
			this.addClass('x-btn-group-notitle');
		}
		this.on('afterlayout', this.onAfterLayout, this);
		Ext.ButtonGroup.superclass.initComponent.call(this);
	},

	applyDefaults : function(c){
		c = Ext.ButtonGroup.superclass.applyDefaults.call(this, c);
		var d = this.internalDefaults;
		if(c.events){
			Ext.applyIf(c.initialConfig, d);
			Ext.apply(c, d);
		}else{
			Ext.applyIf(c, d);
		}
		return c;
	},

	onAfterLayout : function(){
		var bodyWidth = this.body.getFrameWidth('lr') + this.body.dom.firstChild.offsetWidth;
		this.body.setWidth(bodyWidth);
		this.el.setWidth(bodyWidth + this.getFrameWidth());
	}

});

Ext.reg('buttongroup', Ext.ButtonGroup);

(function() {

	var T = Ext.Toolbar;

	Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {



		pageSize : 20,


		displayMsg : 'Displaying {0} - {1} of {2}',

		emptyMsg : 'No data to display',

		beforePageText : 'Page',

		afterPageText : 'of {0}',

		firstText : 'First Page',

		prevText : 'Previous Page',

		nextText : 'Next Page',

		lastText : 'Last Page',

		refreshText : 'Refresh',







		initComponent : function(){
			var pagingItems = [this.first = new T.Button({
				tooltip: this.firstText,
				overflowText: this.firstText,
				iconCls: 'x-tbar-page-first',
				disabled: true,
				handler: this.moveFirst,
				scope: this
			}), this.prev = new T.Button({
				tooltip: this.prevText,
				overflowText: this.prevText,
				iconCls: 'x-tbar-page-prev',
				disabled: true,
				handler: this.movePrevious,
				scope: this
			}), '-', this.beforePageText,
			this.inputItem = new Ext.form.NumberField({
				cls: 'x-tbar-page-number',
				allowDecimals: false,
				allowNegative: false,
				enableKeyEvents: true,
				selectOnFocus: true,
				submitValue: false,
				listeners: {
					scope: this,
					keydown: this.onPagingKeyDown,
					blur: this.onPagingBlur
				}
			}), this.afterTextItem = new T.TextItem({
				text: String.format(this.afterPageText, 1)
			}), '-', this.next = new T.Button({
				tooltip: this.nextText,
				overflowText: this.nextText,
				iconCls: 'x-tbar-page-next',
				disabled: true,
				handler: this.moveNext,
				scope: this
			}), this.last = new T.Button({
				tooltip: this.lastText,
				overflowText: this.lastText,
				iconCls: 'x-tbar-page-last',
				disabled: true,
				handler: this.moveLast,
				scope: this
			}), '-', this.refresh = new T.Button({
				tooltip: this.refreshText,
				overflowText: this.refreshText,
				iconCls: 'x-tbar-loading',
				handler: this.doRefresh,
				scope: this
			})];


			var userItems = this.items || this.buttons || [];
			if (this.prependButtons) {
				this.items = userItems.concat(pagingItems);
			}else{
				this.items = pagingItems.concat(userItems);
			}
			delete this.buttons;
			if(this.displayInfo){
				this.items.push('->');
				this.items.push(this.displayItem = new T.TextItem({}));
			}
			Ext.PagingToolbar.superclass.initComponent.call(this);
			this.addEvents(

				'change',

				'beforechange'
				);
			this.on('afterlayout', this.onFirstLayout, this, {
				single: true
			});
			this.cursor = 0;
			this.bindStore(this.store, true);
		},


		onFirstLayout : function(){
			if(this.dsLoaded){
				this.onLoad.apply(this, this.dsLoaded);
			}
		},


		updateInfo : function(){
			if(this.displayItem){
				var count = this.store.getCount();
				var msg = count == 0 ?
				this.emptyMsg :
				String.format(
					this.displayMsg,
					this.cursor+1, this.cursor+count, this.store.getTotalCount()
					);
				this.displayItem.setText(msg);
			}
		},


		onLoad : function(store, r, o){
			if(!this.rendered){
				this.dsLoaded = [store, r, o];
				return;
			}
			var p = this.getParams();
			this.cursor = (o.params && o.params[p.start]) ? o.params[p.start] : 0;
			var d = this.getPageData(), ap = d.activePage, ps = d.pages;

			this.afterTextItem.setText(String.format(this.afterPageText, d.pages));
			this.inputItem.setValue(ap);
			this.first.setDisabled(ap == 1);
			this.prev.setDisabled(ap == 1);
			this.next.setDisabled(ap == ps);
			this.last.setDisabled(ap == ps);
			this.refresh.enable();
			this.updateInfo();
			this.fireEvent('change', this, d);
		},


		getPageData : function(){
			var total = this.store.getTotalCount();
			return {
				total : total,
				activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),
				pages :  total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
			};
		},


		changePage : function(page){
			this.doLoad(((page-1) * this.pageSize).constrain(0, this.store.getTotalCount()));
		},


		onLoadError : function(){
			if(!this.rendered){
				return;
			}
			this.refresh.enable();
		},


		readPage : function(d){
			var v = this.inputItem.getValue(), pageNum;
			if (!v || isNaN(pageNum = parseInt(v, 10))) {
				this.inputItem.setValue(d.activePage);
				return false;
			}
			return pageNum;
		},

		onPagingFocus : function(){
			this.inputItem.select();
		},


		onPagingBlur : function(e){
			this.inputItem.setValue(this.getPageData().activePage);
		},


		onPagingKeyDown : function(field, e){
			var k = e.getKey(), d = this.getPageData(), pageNum;
			if (k == e.RETURN) {
				e.stopEvent();
				pageNum = this.readPage(d);
				if(pageNum !== false){
					pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;
					this.doLoad(pageNum * this.pageSize);
				}
			}else if (k == e.HOME || k == e.END){
				e.stopEvent();
				pageNum = k == e.HOME ? 1 : d.pages;
				field.setValue(pageNum);
			}else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN){
				e.stopEvent();
				if((pageNum = this.readPage(d))){
					var increment = e.shiftKey ? 10 : 1;
					if(k == e.DOWN || k == e.PAGEDOWN){
						increment *= -1;
					}
					pageNum += increment;
					if(pageNum >= 1 & pageNum <= d.pages){
						field.setValue(pageNum);
					}
				}
			}
		},


		getParams : function(){

			return this.paramNames || this.store.paramNames;
		},


		beforeLoad : function(){
			if(this.rendered && this.refresh){
				this.refresh.disable();
			}
		},


		doLoad : function(start){
			var o = {}, pn = this.getParams();
			o[pn.start] = start;
			o[pn.limit] = this.pageSize;
			if(this.fireEvent('beforechange', this, o) !== false){
				this.store.load({
					params:o
				});
			}
		},


		moveFirst : function(){
			this.doLoad(0);
		},


		movePrevious : function(){
			this.doLoad(Math.max(0, this.cursor-this.pageSize));
		},


		moveNext : function(){
			this.doLoad(this.cursor+this.pageSize);
		},


		moveLast : function(){
			var total = this.store.getTotalCount(),
			extra = total % this.pageSize;

			this.doLoad(extra ? (total - extra) : total - this.pageSize);
		},


		doRefresh : function(){
			this.doLoad(this.cursor);
		},


		bindStore : function(store, initial){
			var doLoad;
			if(!initial && this.store){
				if(store !== this.store && this.store.autoDestroy){
					this.store.destroy();
				}else{
					this.store.un('beforeload', this.beforeLoad, this);
					this.store.un('load', this.onLoad, this);
					this.store.un('exception', this.onLoadError, this);
				}
				if(!store){
					this.store = null;
				}
			}
			if(store){
				store = Ext.StoreMgr.lookup(store);
				store.on({
					scope: this,
					beforeload: this.beforeLoad,
					load: this.onLoad,
					exception: this.onLoadError
				});
				doLoad = true;
			}
			this.store = store;
			if(doLoad){
				this.onLoad(store, null, {});
			}
		},


		unbind : function(store){
			this.bindStore(null);
		},


		bind : function(store){
			this.bindStore(store);
		},


		onDestroy : function(){
			this.bindStore(null);
			Ext.PagingToolbar.superclass.onDestroy.call(this);
		}
	});

})();
Ext.reg('paging', Ext.PagingToolbar);
Ext.History = (function () {
	var iframe, hiddenField;
	var ready = false;
	var currentToken;

	function getHash() {
		var href = location.href, i = href.indexOf("#");
		return i >= 0 ? href.substr(i + 1) : null;
	}

	function doSave() {
		hiddenField.value = currentToken;
	}

	function handleStateChange(token) {
		currentToken = token;
		Ext.History.fireEvent('change', token);
	}

	function updateIFrame (token) {
		var html = ['<html><body><div id="state">',Ext.util.Format.htmlEncode(token),'</div></body></html>'].join('');
		try {
			var doc = iframe.contentWindow.document;
			doc.open();
			doc.write(html);
			doc.close();
			return true;
		} catch (e) {
			return false;
		}
	}

	function checkIFrame() {
		if (!iframe.contentWindow || !iframe.contentWindow.document) {
			setTimeout(checkIFrame, 10);
			return;
		}

		var doc = iframe.contentWindow.document;
		var elem = doc.getElementById("state");
		var token = elem ? elem.innerText : null;

		var hash = getHash();

		setInterval(function () {

			doc = iframe.contentWindow.document;
			elem = doc.getElementById("state");

			var newtoken = elem ? elem.innerText : null;

			var newHash = getHash();

			if (newtoken !== token) {
				token = newtoken;
				handleStateChange(token);
				top.location.hash = token;
				hash = token;
				doSave();
			} else if (newHash !== hash) {
				hash = newHash;
				updateIFrame(newHash);
			}

		}, 50);

		ready = true;

		Ext.History.fireEvent('ready', Ext.History);
	}

	function startUp() {
		currentToken = hiddenField.value ? hiddenField.value : getHash();

		if (Ext.isIE) {
			checkIFrame();
		} else {
			var hash = getHash();
			setInterval(function () {
				var newHash = getHash();
				if (newHash !== hash) {
					hash = newHash;
					handleStateChange(hash);
					doSave();
				}
			}, 50);
			ready = true;
			Ext.History.fireEvent('ready', Ext.History);
		}
	}

	return {

		fieldId: 'x-history-field',

		iframeId: 'x-history-frame',

		events:{},


		init: function (onReady, scope) {
			if(ready) {
				Ext.callback(onReady, scope, [this]);
				return;
			}
			if(!Ext.isReady){
				Ext.onReady(function(){
					Ext.History.init(onReady, scope);
				});
				return;
			}
			hiddenField = Ext.getDom(Ext.History.fieldId);
			if (Ext.isIE) {
				iframe = Ext.getDom(Ext.History.iframeId);
			}
			this.addEvents(

				'ready',

				'change'
				);
			if(onReady){
				this.on('ready', onReady, scope, {
					single:true
				});
			}
			startUp();
		},


		add: function (token, preventDup) {
			if(preventDup !== false){
				if(this.getToken() == token){
					return true;
				}
			}
			if (Ext.isIE) {
				return updateIFrame(token);
			} else {
				top.location.hash = token;
				return true;
			}
		},


		back: function(){
			history.go(-1);
		},


		forward: function(){
			history.go(1);
		},


		getToken: function() {
			return ready ? currentToken : getHash();
		}
	};
})();
Ext.apply(Ext.History, new Ext.util.Observable());
Ext.Tip = Ext.extend(Ext.Panel, {



	minWidth : 40,

	maxWidth : 300,

	shadow : "sides",

	defaultAlign : "tl-bl?",
	autoRender: true,
	quickShowInterval : 250,


	frame:true,
	hidden:true,
	baseCls: 'x-tip',
	floating:{
		shadow:true,
		shim:true,
		useDisplay:true,
		constrain:false
	},
	autoHeight:true,

	closeAction: 'hide',


	initComponent : function(){
		Ext.Tip.superclass.initComponent.call(this);
		if(this.closable && !this.title){
			this.elements += ',header';
		}
	},


	afterRender : function(){
		Ext.Tip.superclass.afterRender.call(this);
		if(this.closable){
			this.addTool({
				id: 'close',
				handler: this[this.closeAction],
				scope: this
			});
		}
	},


	showAt : function(xy){
		Ext.Tip.superclass.show.call(this);
		if(this.measureWidth !== false && (!this.initialConfig || typeof this.initialConfig.width != 'number')){
			this.doAutoWidth();
		}
		if(this.constrainPosition){
			xy = this.el.adjustForConstraints(xy);
		}
		this.setPagePosition(xy[0], xy[1]);
	},


	doAutoWidth : function(adjust){
		adjust = adjust || 0;
		var bw = this.body.getTextWidth();
		if(this.title){
			bw = Math.max(bw, this.header.child('span').getTextWidth(this.title));
		}
		bw += this.getFrameWidth() + (this.closable ? 20 : 0) + this.body.getPadding("lr") + adjust;
		this.setWidth(bw.constrain(this.minWidth, this.maxWidth));


		if(Ext.isIE7 && !this.repainted){
			this.el.repaint();
			this.repainted = true;
		}
	},


	showBy : function(el, pos){
		if(!this.rendered){
			this.render(Ext.getBody());
		}
		this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign));
	},

	initDraggable : function(){
		this.dd = new Ext.Tip.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
		this.header.addClass('x-tip-draggable');
	}
});

Ext.reg('tip', Ext.Tip);


Ext.Tip.DD = function(tip, config){
	Ext.apply(this, config);
	this.tip = tip;
	Ext.Tip.DD.superclass.constructor.call(this, tip.el.id, 'WindowDD-'+tip.id);
	this.setHandleElId(tip.header.id);
	this.scroll = false;
};

Ext.extend(Ext.Tip.DD, Ext.dd.DD, {
	moveOnly:true,
	scroll:false,
	headerOffsets:[100, 25],
	startDrag : function(){
		this.tip.el.disableShadow();
	},
	endDrag : function(e){
		this.tip.el.enableShadow(true);
	}
});
Ext.ToolTip = Ext.extend(Ext.Tip, {




	showDelay : 500,

	hideDelay : 200,

	dismissDelay : 5000,


	trackMouse : false,

	anchorToTarget : true,

	anchorOffset : 0,



	targetCounter : 0,

	constrainPosition : false,


	initComponent : function(){
		Ext.ToolTip.superclass.initComponent.call(this);
		this.lastActive = new Date();
		this.initTarget(this.target);
		this.origAnchor = this.anchor;
	},


	onRender : function(ct, position){
		Ext.ToolTip.superclass.onRender.call(this, ct, position);
		this.anchorCls = 'x-tip-anchor-' + this.getAnchorPosition();
		this.anchorEl = this.el.createChild({
			cls: 'x-tip-anchor ' + this.anchorCls
		});
	},


	afterRender : function(){
		Ext.ToolTip.superclass.afterRender.call(this);
		this.anchorEl.setStyle('z-index', this.el.getZIndex() + 1).setVisibilityMode(Ext.Element.DISPLAY);
	},


	initTarget : function(target){
		var t;
		if((t = Ext.get(target))){
			if(this.target){
				var tg = Ext.get(this.target);
				this.mun(tg, 'mouseover', this.onTargetOver, this);
				this.mun(tg, 'mouseout', this.onTargetOut, this);
				this.mun(tg, 'mousemove', this.onMouseMove, this);
			}
			this.mon(t, {
				mouseover: this.onTargetOver,
				mouseout: this.onTargetOut,
				mousemove: this.onMouseMove,
				scope: this
			});
			this.target = t;
		}
		if(this.anchor){
			this.anchorTarget = this.target;
		}
	},


	onMouseMove : function(e){
		var t = this.delegate ? e.getTarget(this.delegate) : this.triggerElement = true;
		if (t) {
			this.targetXY = e.getXY();
			if (t === this.triggerElement) {
				if(!this.hidden && this.trackMouse){
					this.setPagePosition(this.getTargetXY());
				}
			} else {
				this.hide();
				this.lastActive = new Date(0);
				this.onTargetOver(e);
			}
		} else if (!this.closable && this.isVisible()) {
			this.hide();
		}
	},


	getTargetXY : function(){
		if(this.delegate){
			this.anchorTarget = this.triggerElement;
		}
		if(this.anchor){
			this.targetCounter++;
			var offsets = this.getOffsets(),
			xy = (this.anchorToTarget && !this.trackMouse) ? this.el.getAlignToXY(this.anchorTarget, this.getAnchorAlign()) : this.targetXY,
			dw = Ext.lib.Dom.getViewWidth() - 5,
			dh = Ext.lib.Dom.getViewHeight() - 5,
			de = document.documentElement,
			bd = document.body,
			scrollX = (de.scrollLeft || bd.scrollLeft || 0) + 5,
			scrollY = (de.scrollTop || bd.scrollTop || 0) + 5,
			axy = [xy[0] + offsets[0], xy[1] + offsets[1]],
			sz = this.getSize();

			this.anchorEl.removeClass(this.anchorCls);

			if(this.targetCounter < 2){
				if(axy[0] < scrollX){
					if(this.anchorToTarget){
						this.defaultAlign = 'l-r';
						if(this.mouseOffset){
							this.mouseOffset[0] *= -1;
						}
					}
					this.anchor = 'left';
					return this.getTargetXY();
				}
				if(axy[0]+sz.width > dw){
					if(this.anchorToTarget){
						this.defaultAlign = 'r-l';
						if(this.mouseOffset){
							this.mouseOffset[0] *= -1;
						}
					}
					this.anchor = 'right';
					return this.getTargetXY();
				}
				if(axy[1] < scrollY){
					if(this.anchorToTarget){
						this.defaultAlign = 't-b';
						if(this.mouseOffset){
							this.mouseOffset[1] *= -1;
						}
					}
					this.anchor = 'top';
					return this.getTargetXY();
				}
				if(axy[1]+sz.height > dh){
					if(this.anchorToTarget){
						this.defaultAlign = 'b-t';
						if(this.mouseOffset){
							this.mouseOffset[1] *= -1;
						}
					}
					this.anchor = 'bottom';
					return this.getTargetXY();
				}
			}

			this.anchorCls = 'x-tip-anchor-'+this.getAnchorPosition();
			this.anchorEl.addClass(this.anchorCls);
			this.targetCounter = 0;
			return axy;
		}else{
			var mouseOffset = this.getMouseOffset();
			return [this.targetXY[0]+mouseOffset[0], this.targetXY[1]+mouseOffset[1]];
		}
	},

	getMouseOffset : function(){
		var offset = this.anchor ? [0,0] : [15,18];
		if(this.mouseOffset){
			offset[0] += this.mouseOffset[0];
			offset[1] += this.mouseOffset[1];
		}
		return offset;
	},


	getAnchorPosition : function(){
		if(this.anchor){
			this.tipAnchor = this.anchor.charAt(0);
		}else{
			var m = this.defaultAlign.match(/^([a-z]+)-([a-z]+)(\?)?$/);
			if(!m){
				throw 'AnchorTip.defaultAlign is invalid';
			}
			this.tipAnchor = m[1].charAt(0);
		}

		switch(this.tipAnchor){
			case 't':
				return 'top';
			case 'b':
				return 'bottom';
			case 'r':
				return 'right';
		}
		return 'left';
	},


	getAnchorAlign : function(){
		switch(this.anchor){
			case 'top'  :
				return 'tl-bl';
			case 'left' :
				return 'tl-tr';
			case 'right':
				return 'tr-tl';
			default     :
				return 'bl-tl';
		}
	},


	getOffsets : function(){
		var offsets,
		ap = this.getAnchorPosition().charAt(0);
		if(this.anchorToTarget && !this.trackMouse){
			switch(ap){
				case 't':
					offsets = [0, 9];
					break;
				case 'b':
					offsets = [0, -13];
					break;
				case 'r':
					offsets = [-13, 0];
					break;
				default:
					offsets = [9, 0];
					break;
			}
		}else{
			switch(ap){
				case 't':
					offsets = [-15-this.anchorOffset, 30];
					break;
				case 'b':
					offsets = [-19-this.anchorOffset, -13-this.el.dom.offsetHeight];
					break;
				case 'r':
					offsets = [-15-this.el.dom.offsetWidth, -13-this.anchorOffset];
					break;
				default:
					offsets = [25, -13-this.anchorOffset];
					break;
			}
		}
		var mouseOffset = this.getMouseOffset();
		offsets[0] += mouseOffset[0];
		offsets[1] += mouseOffset[1];

		return offsets;
	},


	onTargetOver : function(e){
		if(this.disabled || e.within(this.target.dom, true)){
			return;
		}
		var t = e.getTarget(this.delegate);
		if (t) {
			this.triggerElement = t;
			this.clearTimer('hide');
			this.targetXY = e.getXY();
			this.delayShow();
		}
	},


	delayShow : function(){
		if(this.hidden && !this.showTimer){
			if(this.lastActive.getElapsed() < this.quickShowInterval){
				this.show();
			}else{
				this.showTimer = this.show.defer(this.showDelay, this);
			}
		}else if(!this.hidden && this.autoHide !== false){
			this.show();
		}
	},


	onTargetOut : function(e){
		if(this.disabled || e.within(this.target.dom, true)){
			return;
		}
		this.clearTimer('show');
		if(this.autoHide !== false){
			this.delayHide();
		}
	},


	delayHide : function(){
		if(!this.hidden && !this.hideTimer){
			this.hideTimer = this.hide.defer(this.hideDelay, this);
		}
	},


	hide: function(){
		this.clearTimer('dismiss');
		this.lastActive = new Date();
		if(this.anchorEl){
			this.anchorEl.hide();
		}
		Ext.ToolTip.superclass.hide.call(this);
		delete this.triggerElement;
	},


	show : function(){
		if(this.anchor){


			this.showAt([-1000,-1000]);
			this.origConstrainPosition = this.constrainPosition;
			this.constrainPosition = false;
			this.anchor = this.origAnchor;
		}
		this.showAt(this.getTargetXY());

		if(this.anchor){
			this.anchorEl.show();
			this.syncAnchor();
			this.constrainPosition = this.origConstrainPosition;
		}else{
			this.anchorEl.hide();
		}
	},


	showAt : function(xy){
		this.lastActive = new Date();
		this.clearTimers();
		Ext.ToolTip.superclass.showAt.call(this, xy);
		if(this.dismissDelay && this.autoHide !== false){
			this.dismissTimer = this.hide.defer(this.dismissDelay, this);
		}
		if(this.anchor && !this.anchorEl.isVisible()){
			this.syncAnchor();
			this.anchorEl.show();
		}else{
			this.anchorEl.hide();
		}
	},


	syncAnchor : function(){
		var anchorPos, targetPos, offset;
		switch(this.tipAnchor.charAt(0)){
			case 't':
				anchorPos = 'b';
				targetPos = 'tl';
				offset = [20+this.anchorOffset, 2];
				break;
			case 'r':
				anchorPos = 'l';
				targetPos = 'tr';
				offset = [-2, 11+this.anchorOffset];
				break;
			case 'b':
				anchorPos = 't';
				targetPos = 'bl';
				offset = [20+this.anchorOffset, -2];
				break;
			default:
				anchorPos = 'r';
				targetPos = 'tl';
				offset = [2, 11+this.anchorOffset];
				break;
		}
		this.anchorEl.alignTo(this.el, anchorPos+'-'+targetPos, offset);
	},


	setPagePosition : function(x, y){
		Ext.ToolTip.superclass.setPagePosition.call(this, x, y);
		if(this.anchor){
			this.syncAnchor();
		}
	},


	clearTimer : function(name){
		name = name + 'Timer';
		clearTimeout(this[name]);
		delete this[name];
	},


	clearTimers : function(){
		this.clearTimer('show');
		this.clearTimer('dismiss');
		this.clearTimer('hide');
	},


	onShow : function(){
		Ext.ToolTip.superclass.onShow.call(this);
		Ext.getDoc().on('mousedown', this.onDocMouseDown, this);
	},


	onHide : function(){
		Ext.ToolTip.superclass.onHide.call(this);
		Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
	},


	onDocMouseDown : function(e){
		if(this.autoHide !== true && !this.closable && !e.within(this.el.dom)){
			this.disable();
			this.doEnable.defer(100, this);
		}
	},


	doEnable : function(){
		if(!this.isDestroyed){
			this.enable();
		}
	},


	onDisable : function(){
		this.clearTimers();
		this.hide();
	},


	adjustPosition : function(x, y){
		if(this.contstrainPosition){
			var ay = this.targetXY[1], h = this.getSize().height;
			if(y <= ay && (y+h) >= ay){
				y = ay-h-5;
			}
		}
		return {
			x : x,
			y: y
		};
	},

	beforeDestroy : function(){
		this.clearTimers();
		Ext.destroy(this.anchorEl);
		delete this.anchorEl;
		delete this.target;
		delete this.anchorTarget;
		delete this.triggerElement;
		Ext.ToolTip.superclass.beforeDestroy.call(this);
	},


	onDestroy : function(){
		Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
		Ext.ToolTip.superclass.onDestroy.call(this);
	}
});

Ext.reg('tooltip', Ext.ToolTip);
Ext.QuickTip = Ext.extend(Ext.ToolTip, {


	interceptTitles : false,


	tagConfig : {
		namespace : "ext",
		attribute : "qtip",
		width : "qwidth",
		target : "target",
		title : "qtitle",
		hide : "hide",
		cls : "qclass",
		align : "qalign",
		anchor : "anchor"
	},


	initComponent : function(){
		this.target = this.target || Ext.getDoc();
		this.targets = this.targets || {};
		Ext.QuickTip.superclass.initComponent.call(this);
	},


	register : function(config){
		var cs = Ext.isArray(config) ? config : arguments;
		for(var i = 0, len = cs.length; i < len; i++){
			var c = cs[i];
			var target = c.target;
			if(target){
				if(Ext.isArray(target)){
					for(var j = 0, jlen = target.length; j < jlen; j++){
						this.targets[Ext.id(target[j])] = c;
					}
				} else{
					this.targets[Ext.id(target)] = c;
				}
			}
		}
	},


	unregister : function(el){
		delete this.targets[Ext.id(el)];
	},


	cancelShow: function(el){
		var at = this.activeTarget;
		el = Ext.get(el).dom;
		if(this.isVisible()){
			if(at && at.el == el){
				this.hide();
			}
		}else if(at && at.el == el){
			this.clearTimer('show');
		}
	},

	getTipCfg: function(e) {
		var t = e.getTarget(),
		ttp,
		cfg;
		if(this.interceptTitles && t.title && Ext.isString(t.title)){
			ttp = t.title;
			t.qtip = ttp;
			t.removeAttribute("title");
			e.preventDefault();
		}else{
			cfg = this.tagConfig;
			ttp = t.qtip || Ext.fly(t).getAttribute(cfg.attribute, cfg.namespace);
		}
		return ttp;
	},


	onTargetOver : function(e){
		if(this.disabled){
			return;
		}
		this.targetXY = e.getXY();
		var t = e.getTarget();
		if(!t || t.nodeType !== 1 || t == document || t == document.body){
			return;
		}
		if(this.activeTarget && ((t == this.activeTarget.el) || Ext.fly(this.activeTarget.el).contains(t))){
			this.clearTimer('hide');
			this.show();
			return;
		}
		if(t && this.targets[t.id]){
			this.activeTarget = this.targets[t.id];
			this.activeTarget.el = t;
			this.anchor = this.activeTarget.anchor;
			if(this.anchor){
				this.anchorTarget = t;
			}
			this.delayShow();
			return;
		}
		var ttp, et = Ext.fly(t), cfg = this.tagConfig, ns = cfg.namespace;
		if(ttp = this.getTipCfg(e)){
			var autoHide = et.getAttribute(cfg.hide, ns);
			this.activeTarget = {
				el: t,
				text: ttp,
				width: et.getAttribute(cfg.width, ns),
				autoHide: autoHide != "user" && autoHide !== 'false',
				title: et.getAttribute(cfg.title, ns),
				cls: et.getAttribute(cfg.cls, ns),
				align: et.getAttribute(cfg.align, ns)

			};
			this.anchor = et.getAttribute(cfg.anchor, ns);
			if(this.anchor){
				this.anchorTarget = t;
			}
			this.delayShow();
		}
	},


	onTargetOut : function(e){


		if (this.activeTarget && e.within(this.activeTarget.el) && !this.getTipCfg(e)) {
			return;
		}

		this.clearTimer('show');
		if(this.autoHide !== false){
			this.delayHide();
		}
	},


	showAt : function(xy){
		var t = this.activeTarget;
		if(t){
			if(!this.rendered){
				this.render(Ext.getBody());
				this.activeTarget = t;
			}
			if(t.width){
				this.setWidth(t.width);
				this.body.setWidth(this.adjustBodyWidth(t.width - this.getFrameWidth()));
				this.measureWidth = false;
			} else{
				this.measureWidth = true;
			}
			this.setTitle(t.title || '');
			this.body.update(t.text);
			this.autoHide = t.autoHide;
			this.dismissDelay = t.dismissDelay || this.dismissDelay;
			if(this.lastCls){
				this.el.removeClass(this.lastCls);
				delete this.lastCls;
			}
			if(t.cls){
				this.el.addClass(t.cls);
				this.lastCls = t.cls;
			}
			if(this.anchor){
				this.constrainPosition = false;
			}else if(t.align){
				xy = this.el.getAlignToXY(t.el, t.align);
				this.constrainPosition = false;
			}else{
				this.constrainPosition = true;
			}
		}
		Ext.QuickTip.superclass.showAt.call(this, xy);
	},


	hide: function(){
		delete this.activeTarget;
		Ext.QuickTip.superclass.hide.call(this);
	}
});
Ext.reg('quicktip', Ext.QuickTip);
Ext.QuickTips = function(){
	var tip,
	disabled = false;

	return {

		init : function(autoRender){
			if(!tip){
				if(!Ext.isReady){
					Ext.onReady(function(){
						Ext.QuickTips.init(autoRender);
					});
					return;
				}
				tip = new Ext.QuickTip({
					elements:'header,body',
					disabled: disabled
				});
				if(autoRender !== false){
					tip.render(Ext.getBody());
				}
			}
		},


		ddDisable : function(){

			if(tip && !disabled){
				tip.disable();
			}
		},


		ddEnable : function(){

			if(tip && !disabled){
				tip.enable();
			}
		},


		enable : function(){
			if(tip){
				tip.enable();
			}
			disabled = false;
		},


		disable : function(){
			if(tip){
				tip.disable();
			}
			disabled = true;
		},


		isEnabled : function(){
			return tip !== undefined && !tip.disabled;
		},


		getQuickTip : function(){
			return tip;
		},


		register : function(){
			tip.register.apply(tip, arguments);
		},


		unregister : function(){
			tip.unregister.apply(tip, arguments);
		},


		tips : function(){
			tip.register.apply(tip, arguments);
		}
	};
}();
Ext.slider.Tip = Ext.extend(Ext.Tip, {
	minWidth: 10,
	offsets : [0, -10],

	init: function(slider) {
		slider.on({
			scope    : this,
			dragstart: this.onSlide,
			drag     : this.onSlide,
			dragend  : this.hide,
			destroy  : this.destroy
		});
	},


	onSlide : function(slider, e, thumb) {
		this.show();
		this.body.update(this.getText(thumb));
		this.doAutoWidth();
		this.el.alignTo(thumb.el, 'b-t?', this.offsets);
	},


	getText : function(thumb) {
		return String(thumb.value);
	}
});


Ext.ux.SliderTip = Ext.slider.Tip;
Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
	rootVisible : true,
	animate : Ext.enableFx,
	lines : true,
	enableDD : false,
	hlDrop : Ext.enableFx,
	pathSeparator : '/',


	bubbleEvents : [],

	initComponent : function(){
		Ext.tree.TreePanel.superclass.initComponent.call(this);

		if(!this.eventModel){
			this.eventModel = new Ext.tree.TreeEventModel(this);
		}


		var l = this.loader;
		if(!l){
			l = new Ext.tree.TreeLoader({
				dataUrl: this.dataUrl,
				requestMethod: this.requestMethod
			});
		}else if(Ext.isObject(l) && !l.load){
			l = new Ext.tree.TreeLoader(l);
		}
		this.loader = l;

		this.nodeHash = {};


		if(this.root){
			var r = this.root;
			delete this.root;
			this.setRootNode(r);
		}


		this.addEvents(


			'append',

			'remove',

			'movenode',

			'insert',

			'beforeappend',

			'beforeremove',

			'beforemovenode',

			'beforeinsert',


			'beforeload',

			'load',

			'textchange',

			'beforeexpandnode',

			'beforecollapsenode',

			'expandnode',

			'disabledchange',

			'collapsenode',

			'beforeclick',

			'click',

			'containerclick',

			'checkchange',

			'beforedblclick',

			'dblclick',

			'containerdblclick',

			'contextmenu',

			'containercontextmenu',

			'beforechildrenrendered',

			'startdrag',

			'enddrag',

			'dragdrop',

			'beforenodedrop',

			'nodedrop',

			'nodedragover'
			);
		if(this.singleExpand){
			this.on('beforeexpandnode', this.restrictExpand, this);
		}
	},


	proxyNodeEvent : function(ename, a1, a2, a3, a4, a5, a6){
		if(ename == 'collapse' || ename == 'expand' || ename == 'beforecollapse' || ename == 'beforeexpand' || ename == 'move' || ename == 'beforemove'){
			ename = ename+'node';
		}

		return this.fireEvent(ename, a1, a2, a3, a4, a5, a6);
	},



	getRootNode : function(){
		return this.root;
	},


	setRootNode : function(node){
		this.destroyRoot();
		if(!node.render){
			node = this.loader.createNode(node);
		}
		this.root = node;
		node.ownerTree = this;
		node.isRoot = true;
		this.registerNode(node);
		if(!this.rootVisible){
			var uiP = node.attributes.uiProvider;
			node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node);
		}
		if(this.innerCt){
			this.clearInnerCt();
			this.renderRoot();
		}
		return node;
	},

	clearInnerCt : function(){
		this.innerCt.update('');
	},


	renderRoot : function(){
		this.root.render();
		if(!this.rootVisible){
			this.root.renderChildren();
		}
	},


	getNodeById : function(id){
		return this.nodeHash[id];
	},


	registerNode : function(node){
		this.nodeHash[node.id] = node;
	},


	unregisterNode : function(node){
		delete this.nodeHash[node.id];
	},


	toString : function(){
		return '[Tree'+(this.id?' '+this.id:'')+']';
	},


	restrictExpand : function(node){
		var p = node.parentNode;
		if(p){
			if(p.expandedChild && p.expandedChild.parentNode == p){
				p.expandedChild.collapse();
			}
			p.expandedChild = node;
		}
	},


	getChecked : function(a, startNode){
		startNode = startNode || this.root;
		var r = [];
		var f = function(){
			if(this.attributes.checked){
				r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a]));
			}
		};
		startNode.cascade(f);
		return r;
	},


	getLoader : function(){
		return this.loader;
	},


	expandAll : function(){
		this.root.expand(true);
	},


	collapseAll : function(){
		this.root.collapse(true);
	},


	getSelectionModel : function(){
		if(!this.selModel){
			this.selModel = new Ext.tree.DefaultSelectionModel();
		}
		return this.selModel;
	},


	expandPath : function(path, attr, callback){
		if(Ext.isEmpty(path)){
			if(callback){
				callback(false, undefined);
			}
			return;
		}
		attr = attr || 'id';
		var keys = path.split(this.pathSeparator);
		var curNode = this.root;
		if(curNode.attributes[attr] != keys[1]){
			if(callback){
				callback(false, null);
			}
			return;
		}
		var index = 1;
		var f = function(){
			if(++index == keys.length){
				if(callback){
					callback(true, curNode);
				}
				return;
			}
			var c = curNode.findChild(attr, keys[index]);
			if(!c){
				if(callback){
					callback(false, curNode);
				}
				return;
			}
			curNode = c;
			c.expand(false, false, f);
		};
		curNode.expand(false, false, f);
	},


	selectPath : function(path, attr, callback){
		if(Ext.isEmpty(path)){
			if(callback){
				callback(false, undefined);
			}
			return;
		}
		attr = attr || 'id';
		var keys = path.split(this.pathSeparator),
		v = keys.pop();
		if(keys.length > 1){
			var f = function(success, node){
				if(success && node){
					var n = node.findChild(attr, v);
					if(n){
						n.select();
						if(callback){
							callback(true, n);
						}
					}else if(callback){
						callback(false, n);
					}
				}else{
					if(callback){
						callback(false, n);
					}
				}
			};
			this.expandPath(keys.join(this.pathSeparator), attr, f);
		}else{
			this.root.select();
			if(callback){
				callback(true, this.root);
			}
		}
	},


	getTreeEl : function(){
		return this.body;
	},


	onRender : function(ct, position){
		Ext.tree.TreePanel.superclass.onRender.call(this, ct, position);
		this.el.addClass('x-tree');
		this.innerCt = this.body.createChild({
			tag:'ul',
			cls:'x-tree-root-ct ' +
			(this.useArrows ? 'x-tree-arrows' : this.lines ? 'x-tree-lines' : 'x-tree-no-lines')
			});
	},


	initEvents : function(){
		Ext.tree.TreePanel.superclass.initEvents.call(this);

		if(this.containerScroll){
			Ext.dd.ScrollManager.register(this.body);
		}
		if((this.enableDD || this.enableDrop) && !this.dropZone){

			this.dropZone = new Ext.tree.TreeDropZone(this, this.dropConfig || {
				ddGroup: this.ddGroup || 'TreeDD',
				appendOnly: this.ddAppendOnly === true
			});
		}
		if((this.enableDD || this.enableDrag) && !this.dragZone){

			this.dragZone = new Ext.tree.TreeDragZone(this, this.dragConfig || {
				ddGroup: this.ddGroup || 'TreeDD',
				scroll: this.ddScroll
			});
		}
		this.getSelectionModel().init(this);
	},


	afterRender : function(){
		Ext.tree.TreePanel.superclass.afterRender.call(this);
		this.renderRoot();
	},

	beforeDestroy : function(){
		if(this.rendered){
			Ext.dd.ScrollManager.unregister(this.body);
			Ext.destroy(this.dropZone, this.dragZone);
		}
		this.destroyRoot();
		Ext.destroy(this.loader);
		this.nodeHash = this.root = this.loader = null;
		Ext.tree.TreePanel.superclass.beforeDestroy.call(this);
	},


	destroyRoot : function(){
		if(this.root && this.root.destroy){
			this.root.destroy(true);
		}
	}



















































});

Ext.tree.TreePanel.nodeTypes = {};

Ext.reg('treepanel', Ext.tree.TreePanel);
Ext.tree.TreeEventModel = function(tree){
	this.tree = tree;
	this.tree.on('render', this.initEvents, this);
};

Ext.tree.TreeEventModel.prototype = {
	initEvents : function(){
		var t = this.tree;

		if(t.trackMouseOver !== false){
			t.mon(t.innerCt, {
				scope: this,
				mouseover: this.delegateOver,
				mouseout: this.delegateOut
			});
		}
		t.mon(t.getTreeEl(), {
			scope: this,
			click: this.delegateClick,
			dblclick: this.delegateDblClick,
			contextmenu: this.delegateContextMenu
		});
	},

	getNode : function(e){
		var t;
		if(t = e.getTarget('.x-tree-node-el', 10)){
			var id = Ext.fly(t, '_treeEvents').getAttribute('tree-node-id', 'ext');
			if(id){
				return this.tree.getNodeById(id);
			}
		}
		return null;
	},

	getNodeTarget : function(e){
		var t = e.getTarget('.x-tree-node-icon', 1);
		if(!t){
			t = e.getTarget('.x-tree-node-el', 6);
		}
		return t;
	},

	delegateOut : function(e, t){
		if(!this.beforeEvent(e)){
			return;
		}
		if(e.getTarget('.x-tree-ec-icon', 1)){
			var n = this.getNode(e);
			this.onIconOut(e, n);
			if(n == this.lastEcOver){
				delete this.lastEcOver;
			}
		}
		if((t = this.getNodeTarget(e)) && !e.within(t, true)){
			this.onNodeOut(e, this.getNode(e));
		}
	},

	delegateOver : function(e, t){
		if(!this.beforeEvent(e)){
			return;
		}
		if(Ext.isGecko && !this.trackingDoc){
			Ext.getBody().on('mouseover', this.trackExit, this);
			this.trackingDoc = true;
		}
		if(this.lastEcOver){
			this.onIconOut(e, this.lastEcOver);
			delete this.lastEcOver;
		}
		if(e.getTarget('.x-tree-ec-icon', 1)){
			this.lastEcOver = this.getNode(e);
			this.onIconOver(e, this.lastEcOver);
		}
		if(t = this.getNodeTarget(e)){
			this.onNodeOver(e, this.getNode(e));
		}
	},

	trackExit : function(e){
		if(this.lastOverNode){
			if(this.lastOverNode.ui && !e.within(this.lastOverNode.ui.getEl())){
				this.onNodeOut(e, this.lastOverNode);
			}
			delete this.lastOverNode;
			Ext.getBody().un('mouseover', this.trackExit, this);
			this.trackingDoc = false;
		}

	},

	delegateClick : function(e, t){
		if(this.beforeEvent(e)){
			if(e.getTarget('input[type=checkbox]', 1)){
				this.onCheckboxClick(e, this.getNode(e));
			}else if(e.getTarget('.x-tree-ec-icon', 1)){
				this.onIconClick(e, this.getNode(e));
			}else if(this.getNodeTarget(e)){
				this.onNodeClick(e, this.getNode(e));
			}
		}else{
			this.checkContainerEvent(e, 'click');
		}
	},

	delegateDblClick : function(e, t){
		if(this.beforeEvent(e)){
			if(this.getNodeTarget(e)){
				this.onNodeDblClick(e, this.getNode(e));
			}
		}else{
			this.checkContainerEvent(e, 'dblclick');
		}
	},

	delegateContextMenu : function(e, t){
		if(this.beforeEvent(e)){
			if(this.getNodeTarget(e)){
				this.onNodeContextMenu(e, this.getNode(e));
			}
		}else{
			this.checkContainerEvent(e, 'contextmenu');
		}
	},

	checkContainerEvent: function(e, type){
		if(this.disabled){
			e.stopEvent();
			return false;
		}
		this.onContainerEvent(e, type);
	},

	onContainerEvent: function(e, type){
		this.tree.fireEvent('container' + type, this.tree, e);
	},

	onNodeClick : function(e, node){
		node.ui.onClick(e);
	},

	onNodeOver : function(e, node){
		this.lastOverNode = node;
		node.ui.onOver(e);
	},

	onNodeOut : function(e, node){
		node.ui.onOut(e);
	},

	onIconOver : function(e, node){
		node.ui.addClass('x-tree-ec-over');
	},

	onIconOut : function(e, node){
		node.ui.removeClass('x-tree-ec-over');
	},

	onIconClick : function(e, node){
		node.ui.ecClick(e);
	},

	onCheckboxClick : function(e, node){
		node.ui.onCheckChange(e);
	},

	onNodeDblClick : function(e, node){
		node.ui.onDblClick(e);
	},

	onNodeContextMenu : function(e, node){
		node.ui.onContextMenu(e);
	},

	beforeEvent : function(e){
		var node = this.getNode(e);
		if(this.disabled || !node || !node.ui){
			e.stopEvent();
			return false;
		}
		return true;
	},

	disable: function(){
		this.disabled = true;
	},

	enable: function(){
		this.disabled = false;
	}
};
Ext.tree.DefaultSelectionModel = Ext.extend(Ext.util.Observable, {

	constructor : function(config){
		this.selNode = null;

		this.addEvents(

			'selectionchange',


			'beforeselect'
			);

		Ext.apply(this, config);
		Ext.tree.DefaultSelectionModel.superclass.constructor.call(this);
	},

	init : function(tree){
		this.tree = tree;
		tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
		tree.on('click', this.onNodeClick, this);
	},

	onNodeClick : function(node, e){
		this.select(node);
	},


	select : function(node,  selectNextNode){

		if (!Ext.fly(node.ui.wrap).isVisible() && selectNextNode) {
			return selectNextNode.call(this, node);
		}
		var last = this.selNode;
		if(node == last){
			node.ui.onSelectedChange(true);
		}else if(this.fireEvent('beforeselect', this, node, last) !== false){
			if(last && last.ui){
				last.ui.onSelectedChange(false);
			}
			this.selNode = node;
			node.ui.onSelectedChange(true);
			this.fireEvent('selectionchange', this, node, last);
		}
		return node;
	},


	unselect : function(node, silent){
		if(this.selNode == node){
			this.clearSelections(silent);
		}
	},


	clearSelections : function(silent){
		var n = this.selNode;
		if(n){
			n.ui.onSelectedChange(false);
			this.selNode = null;
			if(silent !== true){
				this.fireEvent('selectionchange', this, null);
			}
		}
		return n;
	},


	getSelectedNode : function(){
		return this.selNode;
	},


	isSelected : function(node){
		return this.selNode == node;
	},


	selectPrevious : function( s){
		if(!(s = s || this.selNode || this.lastSelNode)){
			return null;
		}

		var ps = s.previousSibling;
		if(ps){
			if(!ps.isExpanded() || ps.childNodes.length < 1){
				return this.select(ps, this.selectPrevious);
			} else{
				var lc = ps.lastChild;
				while(lc && lc.isExpanded() && Ext.fly(lc.ui.wrap).isVisible() && lc.childNodes.length > 0){
					lc = lc.lastChild;
				}
				return this.select(lc, this.selectPrevious);
			}
		} else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){
			return this.select(s.parentNode, this.selectPrevious);
		}
		return null;
	},


	selectNext : function( s){
		if(!(s = s || this.selNode || this.lastSelNode)){
			return null;
		}

		if(s.firstChild && s.isExpanded() && Ext.fly(s.ui.wrap).isVisible()){
			return this.select(s.firstChild, this.selectNext);
		}else if(s.nextSibling){
			return this.select(s.nextSibling, this.selectNext);
		}else if(s.parentNode){
			var newS = null;
			s.parentNode.bubble(function(){
				if(this.nextSibling){
					newS = this.getOwnerTree().selModel.select(this.nextSibling, this.selectNext);
					return false;
				}
			});
			return newS;
		}
		return null;
	},

	onKeyDown : function(e){
		var s = this.selNode || this.lastSelNode;

		var sm = this;
		if(!s){
			return;
		}
		var k = e.getKey();
		switch(k){
			case e.DOWN:
				e.stopEvent();
				this.selectNext();
				break;
			case e.UP:
				e.stopEvent();
				this.selectPrevious();
				break;
			case e.RIGHT:
				e.preventDefault();
				if(s.hasChildNodes()){
					if(!s.isExpanded()){
						s.expand();
					}else if(s.firstChild){
						this.select(s.firstChild, e);
					}
				}
				break;
			case e.LEFT:
				e.preventDefault();
				if(s.hasChildNodes() && s.isExpanded()){
					s.collapse();
				}else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){
					this.select(s.parentNode, e);
				}
				break;
		};
	}
});


Ext.tree.MultiSelectionModel = Ext.extend(Ext.util.Observable, {

	constructor : function(config){
		this.selNodes = [];
		this.selMap = {};
		this.addEvents(

			'selectionchange'
			);
		Ext.apply(this, config);
		Ext.tree.MultiSelectionModel.superclass.constructor.call(this);
	},

	init : function(tree){
		this.tree = tree;
		tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
		tree.on('click', this.onNodeClick, this);
	},

	onNodeClick : function(node, e){
		if(e.ctrlKey && this.isSelected(node)){
			this.unselect(node);
		}else{
			this.select(node, e, e.ctrlKey);
		}
	},


	select : function(node, e, keepExisting){
		if(keepExisting !== true){
			this.clearSelections(true);
		}
		if(this.isSelected(node)){
			this.lastSelNode = node;
			return node;
		}
		this.selNodes.push(node);
		this.selMap[node.id] = node;
		this.lastSelNode = node;
		node.ui.onSelectedChange(true);
		this.fireEvent('selectionchange', this, this.selNodes);
		return node;
	},


	unselect : function(node){
		if(this.selMap[node.id]){
			node.ui.onSelectedChange(false);
			var sn = this.selNodes;
			var index = sn.indexOf(node);
			if(index != -1){
				this.selNodes.splice(index, 1);
			}
			delete this.selMap[node.id];
			this.fireEvent('selectionchange', this, this.selNodes);
		}
	},


	clearSelections : function(suppressEvent){
		var sn = this.selNodes;
		if(sn.length > 0){
			for(var i = 0, len = sn.length; i < len; i++){
				sn[i].ui.onSelectedChange(false);
			}
			this.selNodes = [];
			this.selMap = {};
			if(suppressEvent !== true){
				this.fireEvent('selectionchange', this, this.selNodes);
			}
		}
	},


	isSelected : function(node){
		return this.selMap[node.id] ? true : false;
	},


	getSelectedNodes : function(){
		return this.selNodes.concat([]);
	},

	onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown,

	selectNext : Ext.tree.DefaultSelectionModel.prototype.selectNext,

	selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious
});
Ext.data.Tree = Ext.extend(Ext.util.Observable, {

	constructor: function(root){
		this.nodeHash = {};

		this.root = null;
		if(root){
			this.setRootNode(root);
		}
		this.addEvents(

			"append",

			"remove",

			"move",

			"insert",

			"beforeappend",

			"beforeremove",

			"beforemove",

			"beforeinsert"
			);
		Ext.data.Tree.superclass.constructor.call(this);
	},


	pathSeparator: "/",


	proxyNodeEvent : function(){
		return this.fireEvent.apply(this, arguments);
	},


	getRootNode : function(){
		return this.root;
	},


	setRootNode : function(node){
		this.root = node;
		node.ownerTree = this;
		node.isRoot = true;
		this.registerNode(node);
		return node;
	},


	getNodeById : function(id){
		return this.nodeHash[id];
	},


	registerNode : function(node){
		this.nodeHash[node.id] = node;
	},


	unregisterNode : function(node){
		delete this.nodeHash[node.id];
	},

	toString : function(){
		return "[Tree"+(this.id?" "+this.id:"")+"]";
	}
});


Ext.data.Node = Ext.extend(Ext.util.Observable, {

	constructor: function(attributes){

		this.attributes = attributes || {};
		this.leaf = this.attributes.leaf;

		this.id = this.attributes.id;
		if(!this.id){
			this.id = Ext.id(null, "xnode-");
			this.attributes.id = this.id;
		}

		this.childNodes = [];

		this.parentNode = null;

		this.firstChild = null;

		this.lastChild = null;

		this.previousSibling = null;

		this.nextSibling = null;

		this.addEvents({

			"append" : true,

			"remove" : true,

			"move" : true,

			"insert" : true,

			"beforeappend" : true,

			"beforeremove" : true,

			"beforemove" : true,

			"beforeinsert" : true
		});
		this.listeners = this.attributes.listeners;
		Ext.data.Node.superclass.constructor.call(this);
	},


	fireEvent : function(evtName){

		if(Ext.data.Node.superclass.fireEvent.apply(this, arguments) === false){
			return false;
		}

		var ot = this.getOwnerTree();
		if(ot){
			if(ot.proxyNodeEvent.apply(ot, arguments) === false){
				return false;
			}
		}
		return true;
	},


	isLeaf : function(){
		return this.leaf === true;
	},


	setFirstChild : function(node){
		this.firstChild = node;
	},


	setLastChild : function(node){
		this.lastChild = node;
	},



	isLast : function(){
		return (!this.parentNode ? true : this.parentNode.lastChild == this);
	},


	isFirst : function(){
		return (!this.parentNode ? true : this.parentNode.firstChild == this);
	},


	hasChildNodes : function(){
		return !this.isLeaf() && this.childNodes.length > 0;
	},


	isExpandable : function(){
		return this.attributes.expandable || this.hasChildNodes();
	},


	appendChild : function(node){
		var multi = false;
		if(Ext.isArray(node)){
			multi = node;
		}else if(arguments.length > 1){
			multi = arguments;
		}

		if(multi){
			for(var i = 0, len = multi.length; i < len; i++) {
				this.appendChild(multi[i]);
			}
		}else{
			if(this.fireEvent("beforeappend", this.ownerTree, this, node) === false){
				return false;
			}
			var index = this.childNodes.length;
			var oldParent = node.parentNode;

			if(oldParent){
				if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index) === false){
					return false;
				}
				oldParent.removeChild(node);
			}
			index = this.childNodes.length;
			if(index === 0){
				this.setFirstChild(node);
			}
			this.childNodes.push(node);
			node.parentNode = this;
			var ps = this.childNodes[index-1];
			if(ps){
				node.previousSibling = ps;
				ps.nextSibling = node;
			}else{
				node.previousSibling = null;
			}
			node.nextSibling = null;
			this.setLastChild(node);
			node.setOwnerTree(this.getOwnerTree());
			this.fireEvent("append", this.ownerTree, this, node, index);
			if(oldParent){
				node.fireEvent("move", this.ownerTree, node, oldParent, this, index);
			}
			return node;
		}
	},


	removeChild : function(node, destroy){
		var index = this.childNodes.indexOf(node);
		if(index == -1){
			return false;
		}
		if(this.fireEvent("beforeremove", this.ownerTree, this, node) === false){
			return false;
		}


		this.childNodes.splice(index, 1);


		if(node.previousSibling){
			node.previousSibling.nextSibling = node.nextSibling;
		}
		if(node.nextSibling){
			node.nextSibling.previousSibling = node.previousSibling;
		}


		if(this.firstChild == node){
			this.setFirstChild(node.nextSibling);
		}
		if(this.lastChild == node){
			this.setLastChild(node.previousSibling);
		}

		this.fireEvent("remove", this.ownerTree, this, node);
		if(destroy){
			node.destroy(true);
		}else{
			node.clear();
		}
		return node;
	},


	clear : function(destroy){

		this.setOwnerTree(null, destroy);
		this.parentNode = this.previousSibling = this.nextSibling = null;
		if(destroy){
			this.firstChild = this.lastChild = null;
		}
	},


	destroy : function( silent){

		if(silent === true){
			this.purgeListeners();
			this.clear(true);
			Ext.each(this.childNodes, function(n){
				n.destroy(true);
			});
			this.childNodes = null;
		}else{
			this.remove(true);
		}
	},


	insertBefore : function(node, refNode){
		if(!refNode){
			return this.appendChild(node);
		}

		if(node == refNode){
			return false;
		}

		if(this.fireEvent("beforeinsert", this.ownerTree, this, node, refNode) === false){
			return false;
		}
		var index = this.childNodes.indexOf(refNode);
		var oldParent = node.parentNode;
		var refIndex = index;


		if(oldParent == this && this.childNodes.indexOf(node) < index){
			refIndex--;
		}


		if(oldParent){
			if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index, refNode) === false){
				return false;
			}
			oldParent.removeChild(node);
		}
		if(refIndex === 0){
			this.setFirstChild(node);
		}
		this.childNodes.splice(refIndex, 0, node);
		node.parentNode = this;
		var ps = this.childNodes[refIndex-1];
		if(ps){
			node.previousSibling = ps;
			ps.nextSibling = node;
		}else{
			node.previousSibling = null;
		}
		node.nextSibling = refNode;
		refNode.previousSibling = node;
		node.setOwnerTree(this.getOwnerTree());
		this.fireEvent("insert", this.ownerTree, this, node, refNode);
		if(oldParent){
			node.fireEvent("move", this.ownerTree, node, oldParent, this, refIndex, refNode);
		}
		return node;
	},


	remove : function(destroy){
		if (this.parentNode) {
			this.parentNode.removeChild(this, destroy);
		}
		return this;
	},


	removeAll : function(destroy){
		var cn = this.childNodes,
		n;
		while((n = cn[0])){
			this.removeChild(n, destroy);
		}
		return this;
	},


	item : function(index){
		return this.childNodes[index];
	},


	replaceChild : function(newChild, oldChild){
		var s = oldChild ? oldChild.nextSibling : null;
		this.removeChild(oldChild);
		this.insertBefore(newChild, s);
		return oldChild;
	},


	indexOf : function(child){
		return this.childNodes.indexOf(child);
	},


	getOwnerTree : function(){

		if(!this.ownerTree){
			var p = this;
			while(p){
				if(p.ownerTree){
					this.ownerTree = p.ownerTree;
					break;
				}
				p = p.parentNode;
			}
		}
		return this.ownerTree;
	},


	getDepth : function(){
		var depth = 0;
		var p = this;
		while(p.parentNode){
			++depth;
			p = p.parentNode;
		}
		return depth;
	},


	setOwnerTree : function(tree, destroy){

		if(tree != this.ownerTree){
			if(this.ownerTree){
				this.ownerTree.unregisterNode(this);
			}
			this.ownerTree = tree;

			if(destroy !== true){
				Ext.each(this.childNodes, function(n){
					n.setOwnerTree(tree);
				});
			}
			if(tree){
				tree.registerNode(this);
			}
		}
	},


	setId: function(id){
		if(id !== this.id){
			var t = this.ownerTree;
			if(t){
				t.unregisterNode(this);
			}
			this.id = this.attributes.id = id;
			if(t){
				t.registerNode(this);
			}
			this.onIdChange(id);
		}
	},


	onIdChange: Ext.emptyFn,


	getPath : function(attr){
		attr = attr || "id";
		var p = this.parentNode;
		var b = [this.attributes[attr]];
		while(p){
			b.unshift(p.attributes[attr]);
			p = p.parentNode;
		}
		var sep = this.getOwnerTree().pathSeparator;
		return sep + b.join(sep);
	},


	bubble : function(fn, scope, args){
		var p = this;
		while(p){
			if(fn.apply(scope || p, args || [p]) === false){
				break;
			}
			p = p.parentNode;
		}
	},


	cascade : function(fn, scope, args){
		if(fn.apply(scope || this, args || [this]) !== false){
			var cs = this.childNodes;
			for(var i = 0, len = cs.length; i < len; i++) {
				cs[i].cascade(fn, scope, args);
			}
		}
	},


	eachChild : function(fn, scope, args){
		var cs = this.childNodes;
		for(var i = 0, len = cs.length; i < len; i++) {
			if(fn.apply(scope || cs[i], args || [cs[i]]) === false){
				break;
			}
		}
	},


	findChild : function(attribute, value, deep){
		return this.findChildBy(function(){
			return this.attributes[attribute] == value;
		}, null, deep);
	},


	findChildBy : function(fn, scope, deep){
		var cs = this.childNodes,
		len = cs.length,
		i = 0,
		n,
		res;
		for(; i < len; i++){
			n = cs[i];
			if(fn.call(scope || n, n) === true){
				return n;
			}else if (deep){
				res = n.findChildBy(fn, scope, deep);
				if(res != null){
					return res;
				}
			}

		}
		return null;
	},


	sort : function(fn, scope){
		var cs = this.childNodes;
		var len = cs.length;
		if(len > 0){
			var sortFn = scope ? function(){
				fn.apply(scope, arguments);
			} : fn;
			cs.sort(sortFn);
			for(var i = 0; i < len; i++){
				var n = cs[i];
				n.previousSibling = cs[i-1];
				n.nextSibling = cs[i+1];
				if(i === 0){
					this.setFirstChild(n);
				}
				if(i == len-1){
					this.setLastChild(n);
				}
			}
		}
	},


	contains : function(node){
		return node.isAncestor(this);
	},


	isAncestor : function(node){
		var p = this.parentNode;
		while(p){
			if(p == node){
				return true;
			}
			p = p.parentNode;
		}
		return false;
	},

	toString : function(){
		return "[Node"+(this.id?" "+this.id:"")+"]";
	}
});
Ext.tree.TreeNode = Ext.extend(Ext.data.Node, {

	constructor : function(attributes){
		attributes = attributes || {};
		if(Ext.isString(attributes)){
			attributes = {
				text: attributes
			};
		}
		this.childrenRendered = false;
		this.rendered = false;
		Ext.tree.TreeNode.superclass.constructor.call(this, attributes);
		this.expanded = attributes.expanded === true;
		this.isTarget = attributes.isTarget !== false;
		this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;
		this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;


		this.text = attributes.text;

		this.disabled = attributes.disabled === true;

		this.hidden = attributes.hidden === true;

		this.addEvents(

			'textchange',

			'beforeexpand',

			'beforecollapse',

			'expand',

			'disabledchange',

			'collapse',

			'beforeclick',

			'click',

			'checkchange',

			'beforedblclick',

			'dblclick',

			'contextmenu',

			'beforechildrenrendered'
			);

		var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;


		this.ui = new uiClass(this);
	},

	preventHScroll : true,

	isExpanded : function(){
		return this.expanded;
	},


	getUI : function(){
		return this.ui;
	},

	getLoader : function(){
		var owner;
		return this.loader || ((owner = this.getOwnerTree()) && owner.loader ? owner.loader : (this.loader = new Ext.tree.TreeLoader()));
	},


	setFirstChild : function(node){
		var of = this.firstChild;
		Ext.tree.TreeNode.superclass.setFirstChild.call(this, node);
		if(this.childrenRendered && of && node != of){
			of.renderIndent(true, true);
		}
		if(this.rendered){
			this.renderIndent(true, true);
		}
	},


	setLastChild : function(node){
		var ol = this.lastChild;
		Ext.tree.TreeNode.superclass.setLastChild.call(this, node);
		if(this.childrenRendered && ol && node != ol){
			ol.renderIndent(true, true);
		}
		if(this.rendered){
			this.renderIndent(true, true);
		}
	},



	appendChild : function(n){
		if(!n.render && !Ext.isArray(n)){
			n = this.getLoader().createNode(n);
		}
		var node = Ext.tree.TreeNode.superclass.appendChild.call(this, n);
		if(node && this.childrenRendered){
			node.render();
		}
		this.ui.updateExpandIcon();
		return node;
	},


	removeChild : function(node, destroy){
		this.ownerTree.getSelectionModel().unselect(node);
		Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);

		if(!destroy){
			var rendered = node.ui.rendered;

			if(rendered){
				node.ui.remove();
			}
			if(rendered && this.childNodes.length < 1){
				this.collapse(false, false);
			}else{
				this.ui.updateExpandIcon();
			}
			if(!this.firstChild && !this.isHiddenRoot()){
				this.childrenRendered = false;
			}
		}
		return node;
	},


	insertBefore : function(node, refNode){
		if(!node.render){
			node = this.getLoader().createNode(node);
		}
		var newNode = Ext.tree.TreeNode.superclass.insertBefore.call(this, node, refNode);
		if(newNode && refNode && this.childrenRendered){
			node.render();
		}
		this.ui.updateExpandIcon();
		return newNode;
	},


	setText : function(text){
		var oldText = this.text;
		this.text = this.attributes.text = text;
		if(this.rendered){
			this.ui.onTextChange(this, text, oldText);
		}
		this.fireEvent('textchange', this, text, oldText);
	},


	setIconCls : function(cls){
		var old = this.attributes.iconCls;
		this.attributes.iconCls = cls;
		if(this.rendered){
			this.ui.onIconClsChange(this, cls, old);
		}
	},


	setTooltip : function(tip, title){
		this.attributes.qtip = tip;
		this.attributes.qtipTitle = title;
		if(this.rendered){
			this.ui.onTipChange(this, tip, title);
		}
	},


	setIcon : function(icon){
		this.attributes.icon = icon;
		if(this.rendered){
			this.ui.onIconChange(this, icon);
		}
	},


	setHref : function(href, target){
		this.attributes.href = href;
		this.attributes.hrefTarget = target;
		if(this.rendered){
			this.ui.onHrefChange(this, href, target);
		}
	},


	setCls : function(cls){
		var old = this.attributes.cls;
		this.attributes.cls = cls;
		if(this.rendered){
			this.ui.onClsChange(this, cls, old);
		}
	},


	select : function(){
		var t = this.getOwnerTree();
		if(t){
			t.getSelectionModel().select(this);
		}
	},


	unselect : function(silent){
		var t = this.getOwnerTree();
		if(t){
			t.getSelectionModel().unselect(this, silent);
		}
	},


	isSelected : function(){
		var t = this.getOwnerTree();
		return t ? t.getSelectionModel().isSelected(this) : false;
	},


	expand : function(deep, anim, callback, scope){
		if(!this.expanded){
			if(this.fireEvent('beforeexpand', this, deep, anim) === false){
				return;
			}
			if(!this.childrenRendered){
				this.renderChildren();
			}
			this.expanded = true;
			if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){
				this.ui.animExpand(function(){
					this.fireEvent('expand', this);
					this.runCallback(callback, scope || this, [this]);
					if(deep === true){
						this.expandChildNodes(true, true);
					}
				}.createDelegate(this));
				return;
			}else{
				this.ui.expand();
				this.fireEvent('expand', this);
				this.runCallback(callback, scope || this, [this]);
			}
		}else{
			this.runCallback(callback, scope || this, [this]);
		}
		if(deep === true){
			this.expandChildNodes(true);
		}
	},

	runCallback : function(cb, scope, args){
		if(Ext.isFunction(cb)){
			cb.apply(scope, args);
		}
	},

	isHiddenRoot : function(){
		return this.isRoot && !this.getOwnerTree().rootVisible;
	},


	collapse : function(deep, anim, callback, scope){
		if(this.expanded && !this.isHiddenRoot()){
			if(this.fireEvent('beforecollapse', this, deep, anim) === false){
				return;
			}
			this.expanded = false;
			if((this.getOwnerTree().animate && anim !== false) || anim){
				this.ui.animCollapse(function(){
					this.fireEvent('collapse', this);
					this.runCallback(callback, scope || this, [this]);
					if(deep === true){
						this.collapseChildNodes(true);
					}
				}.createDelegate(this));
				return;
			}else{
				this.ui.collapse();
				this.fireEvent('collapse', this);
				this.runCallback(callback, scope || this, [this]);
			}
		}else if(!this.expanded){
			this.runCallback(callback, scope || this, [this]);
		}
		if(deep === true){
			var cs = this.childNodes;
			for(var i = 0, len = cs.length; i < len; i++) {
				cs[i].collapse(true, false);
			}
		}
	},


	delayedExpand : function(delay){
		if(!this.expandProcId){
			this.expandProcId = this.expand.defer(delay, this);
		}
	},


	cancelExpand : function(){
		if(this.expandProcId){
			clearTimeout(this.expandProcId);
		}
		this.expandProcId = false;
	},


	toggle : function(){
		if(this.expanded){
			this.collapse();
		}else{
			this.expand();
		}
	},


	ensureVisible : function(callback, scope){
		var tree = this.getOwnerTree();
		tree.expandPath(this.parentNode ? this.parentNode.getPath() : this.getPath(), false, function(){
			var node = tree.getNodeById(this.id);
			tree.getTreeEl().scrollChildIntoView(node.ui.anchor);
			this.runCallback(callback, scope || this, [this]);
		}.createDelegate(this));
	},


	expandChildNodes : function(deep, anim) {
		var cs = this.childNodes,
		i,
		len = cs.length;
		for (i = 0; i < len; i++) {
			cs[i].expand(deep, anim);
		}
	},


	collapseChildNodes : function(deep){
		var cs = this.childNodes;
		for(var i = 0, len = cs.length; i < len; i++) {
			cs[i].collapse(deep);
		}
	},


	disable : function(){
		this.disabled = true;
		this.unselect();
		if(this.rendered && this.ui.onDisableChange){
			this.ui.onDisableChange(this, true);
		}
		this.fireEvent('disabledchange', this, true);
	},


	enable : function(){
		this.disabled = false;
		if(this.rendered && this.ui.onDisableChange){
			this.ui.onDisableChange(this, false);
		}
		this.fireEvent('disabledchange', this, false);
	},


	renderChildren : function(suppressEvent){
		if(suppressEvent !== false){
			this.fireEvent('beforechildrenrendered', this);
		}
		var cs = this.childNodes;
		for(var i = 0, len = cs.length; i < len; i++){
			cs[i].render(true);
		}
		this.childrenRendered = true;
	},


	sort : function(fn, scope){
		Ext.tree.TreeNode.superclass.sort.apply(this, arguments);
		if(this.childrenRendered){
			var cs = this.childNodes;
			for(var i = 0, len = cs.length; i < len; i++){
				cs[i].render(true);
			}
		}
	},


	render : function(bulkRender){
		this.ui.render(bulkRender);
		if(!this.rendered){

			this.getOwnerTree().registerNode(this);
			this.rendered = true;
			if(this.expanded){
				this.expanded = false;
				this.expand(false, false);
			}
		}
	},


	renderIndent : function(deep, refresh){
		if(refresh){
			this.ui.childIndent = null;
		}
		this.ui.renderIndent();
		if(deep === true && this.childrenRendered){
			var cs = this.childNodes;
			for(var i = 0, len = cs.length; i < len; i++){
				cs[i].renderIndent(true, refresh);
			}
		}
	},

	beginUpdate : function(){
		this.childrenRendered = false;
	},

	endUpdate : function(){
		if(this.expanded && this.rendered){
			this.renderChildren();
		}
	},


	destroy : function(silent){
		if(silent === true){
			this.unselect(true);
		}
		Ext.tree.TreeNode.superclass.destroy.call(this, silent);
		Ext.destroy(this.ui, this.loader);
		this.ui = this.loader = null;
	},


	onIdChange : function(id){
		this.ui.onIdChange(id);
	}
});

Ext.tree.TreePanel.nodeTypes.node = Ext.tree.TreeNode;
Ext.tree.AsyncTreeNode = function(config){
	this.loaded = config && config.loaded === true;
	this.loading = false;
	Ext.tree.AsyncTreeNode.superclass.constructor.apply(this, arguments);

	this.addEvents('beforeload', 'load');


};
Ext.extend(Ext.tree.AsyncTreeNode, Ext.tree.TreeNode, {
	expand : function(deep, anim, callback, scope){
		if(this.loading){
			var timer;
			var f = function(){
				if(!this.loading){
					clearInterval(timer);
					this.expand(deep, anim, callback, scope);
				}
			}.createDelegate(this);
			timer = setInterval(f, 200);
			return;
		}
		if(!this.loaded){
			if(this.fireEvent("beforeload", this) === false){
				return;
			}
			this.loading = true;
			this.ui.beforeLoad(this);
			var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader();
			if(loader){
				loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback, scope]), this);
				return;
			}
		}
		Ext.tree.AsyncTreeNode.superclass.expand.call(this, deep, anim, callback, scope);
	},


	isLoading : function(){
		return this.loading;
	},

	loadComplete : function(deep, anim, callback, scope){
		this.loading = false;
		this.loaded = true;
		this.ui.afterLoad(this);
		this.fireEvent("load", this);
		this.expand(deep, anim, callback, scope);
	},


	isLoaded : function(){
		return this.loaded;
	},

	hasChildNodes : function(){
		if(!this.isLeaf() && !this.loaded){
			return true;
		}else{
			return Ext.tree.AsyncTreeNode.superclass.hasChildNodes.call(this);
		}
	},


	reload : function(callback, scope){
		this.collapse(false, false);
		while(this.firstChild){
			this.removeChild(this.firstChild).destroy();
		}
		this.childrenRendered = false;
		this.loaded = false;
		if(this.isHiddenRoot()){
			this.expanded = false;
		}
		this.expand(false, false, callback, scope);
	}
});

Ext.tree.TreePanel.nodeTypes.async = Ext.tree.AsyncTreeNode;
Ext.tree.TreeNodeUI = Ext.extend(Object, {

	constructor : function(node){
		Ext.apply(this, {
			node: node,
			rendered: false,
			animating: false,
			wasLeaf: true,
			ecc: 'x-tree-ec-icon x-tree-elbow',
			emptyIcon: Ext.BLANK_IMAGE_URL
		});
	},


	removeChild : function(node){
		if(this.rendered){
			this.ctNode.removeChild(node.ui.getEl());
		}
	},


	beforeLoad : function(){
		this.addClass("x-tree-node-loading");
	},


	afterLoad : function(){
		this.removeClass("x-tree-node-loading");
	},


	onTextChange : function(node, text, oldText){
		if(this.rendered){
			this.textNode.innerHTML = text;
		}
	},


	onIconClsChange : function(node, cls, oldCls){
		if(this.rendered){
			Ext.fly(this.iconNode).replaceClass(oldCls, cls);
		}
	},


	onIconChange : function(node, icon){
		if(this.rendered){

			var empty = Ext.isEmpty(icon);
			this.iconNode.src = empty ? this.emptyIcon : icon;
			Ext.fly(this.iconNode)[empty ? 'removeClass' : 'addClass']('x-tree-node-inline-icon');
		}
	},


	onTipChange : function(node, tip, title){
		if(this.rendered){
			var hasTitle = Ext.isDefined(title);
			if(this.textNode.setAttributeNS){
				this.textNode.setAttributeNS("ext", "qtip", tip);
				if(hasTitle){
					this.textNode.setAttributeNS("ext", "qtitle", title);
				}
			}else{
				this.textNode.setAttribute("ext:qtip", tip);
				if(hasTitle){
					this.textNode.setAttribute("ext:qtitle", title);
				}
			}
		}
	},


	onHrefChange : function(node, href, target){
		if(this.rendered){
			this.anchor.href = this.getHref(href);
			if(Ext.isDefined(target)){
				this.anchor.target = target;
			}
		}
	},


	onClsChange : function(node, cls, oldCls){
		if(this.rendered){
			Ext.fly(this.elNode).replaceClass(oldCls, cls);
		}
	},


	onDisableChange : function(node, state){
		this.disabled = state;
		if (this.checkbox) {
			this.checkbox.disabled = state;
		}
		this[state ? 'addClass' : 'removeClass']('x-tree-node-disabled');
	},


	onSelectedChange : function(state){
		if(state){
			this.focus();
			this.addClass("x-tree-selected");
		}else{

			this.removeClass("x-tree-selected");
		}
	},


	onMove : function(tree, node, oldParent, newParent, index, refNode){
		this.childIndent = null;
		if(this.rendered){
			var targetNode = newParent.ui.getContainer();
			if(!targetNode){
				this.holder = document.createElement("div");
				this.holder.appendChild(this.wrap);
				return;
			}
			var insertBefore = refNode ? refNode.ui.getEl() : null;
			if(insertBefore){
				targetNode.insertBefore(this.wrap, insertBefore);
			}else{
				targetNode.appendChild(this.wrap);
			}
			this.node.renderIndent(true, oldParent != newParent);
		}
	},


	addClass : function(cls){
		if(this.elNode){
			Ext.fly(this.elNode).addClass(cls);
		}
	},


	removeClass : function(cls){
		if(this.elNode){
			Ext.fly(this.elNode).removeClass(cls);
		}
	},


	remove : function(){
		if(this.rendered){
			this.holder = document.createElement("div");
			this.holder.appendChild(this.wrap);
		}
	},


	fireEvent : function(){
		return this.node.fireEvent.apply(this.node, arguments);
	},


	initEvents : function(){
		this.node.on("move", this.onMove, this);

		if(this.node.disabled){
			this.onDisableChange(this.node, true);
		}
		if(this.node.hidden){
			this.hide();
		}
		var ot = this.node.getOwnerTree();
		var dd = ot.enableDD || ot.enableDrag || ot.enableDrop;
		if(dd && (!this.node.isRoot || ot.rootVisible)){
			Ext.dd.Registry.register(this.elNode, {
				node: this.node,
				handles: this.getDDHandles(),
				isHandle: false
			});
		}
	},


	getDDHandles : function(){
		return [this.iconNode, this.textNode, this.elNode];
	},


	hide : function(){
		this.node.hidden = true;
		if(this.wrap){
			this.wrap.style.display = "none";
		}
	},


	show : function(){
		this.node.hidden = false;
		if(this.wrap){
			this.wrap.style.display = "";
		}
	},


	onContextMenu : function(e){
		if (this.node.hasListener("contextmenu") || this.node.getOwnerTree().hasListener("contextmenu")) {
			e.preventDefault();
			this.focus();
			this.fireEvent("contextmenu", this.node, e);
		}
	},


	onClick : function(e){
		if(this.dropping){
			e.stopEvent();
			return;
		}
		if(this.fireEvent("beforeclick", this.node, e) !== false){
			var a = e.getTarget('a');
			if(!this.disabled && this.node.attributes.href && a){
				this.fireEvent("click", this.node, e);
				return;
			}else if(a && e.ctrlKey){
				e.stopEvent();
			}
			e.preventDefault();
			if(this.disabled){
				return;
			}

			if(this.node.attributes.singleClickExpand && !this.animating && this.node.isExpandable()){
				this.node.toggle();
			}

			this.fireEvent("click", this.node, e);
		}else{
			e.stopEvent();
		}
	},


	onDblClick : function(e){
		e.preventDefault();
		if(this.disabled){
			return;
		}
		if(this.fireEvent("beforedblclick", this.node, e) !== false){
			if(this.checkbox){
				this.toggleCheck();
			}
			if(!this.animating && this.node.isExpandable()){
				this.node.toggle();
			}
			this.fireEvent("dblclick", this.node, e);
		}
	},

	onOver : function(e){
		this.addClass('x-tree-node-over');
	},

	onOut : function(e){
		this.removeClass('x-tree-node-over');
	},


	onCheckChange : function(){
		var checked = this.checkbox.checked;

		this.checkbox.defaultChecked = checked;
		this.node.attributes.checked = checked;
		this.fireEvent('checkchange', this.node, checked);
	},


	ecClick : function(e){
		if(!this.animating && this.node.isExpandable()){
			this.node.toggle();
		}
	},


	startDrop : function(){
		this.dropping = true;
	},


	endDrop : function(){
		setTimeout(function(){
			this.dropping = false;
		}.createDelegate(this), 50);
	},


	expand : function(){
		this.updateExpandIcon();
		this.ctNode.style.display = "";
	},


	focus : function(){
		if(!this.node.preventHScroll){
			try{
				this.anchor.focus();
			}catch(e){}
		}else{
			try{
				var noscroll = this.node.getOwnerTree().getTreeEl().dom;
				var l = noscroll.scrollLeft;
				this.anchor.focus();
				noscroll.scrollLeft = l;
			}catch(e){}
		}
	},


	toggleCheck : function(value){
		var cb = this.checkbox;
		if(cb){
			cb.checked = (value === undefined ? !cb.checked : value);
			this.onCheckChange();
		}
	},


	blur : function(){
		try{
			this.anchor.blur();
		}catch(e){}
	},


	animExpand : function(callback){
		var ct = Ext.get(this.ctNode);
		ct.stopFx();
		if(!this.node.isExpandable()){
			this.updateExpandIcon();
			this.ctNode.style.display = "";
			Ext.callback(callback);
			return;
		}
		this.animating = true;
		this.updateExpandIcon();

		ct.slideIn('t', {
			callback : function(){
				this.animating = false;
				Ext.callback(callback);
			},
			scope: this,
			duration: this.node.ownerTree.duration || .25
		});
	},


	highlight : function(){
		var tree = this.node.getOwnerTree();
		Ext.fly(this.wrap).highlight(
			tree.hlColor || "C3DAF9",
			{
				endColor: tree.hlBaseColor
				}
			);
	},


	collapse : function(){
		this.updateExpandIcon();
		this.ctNode.style.display = "none";
	},


	animCollapse : function(callback){
		var ct = Ext.get(this.ctNode);
		ct.enableDisplayMode('block');
		ct.stopFx();

		this.animating = true;
		this.updateExpandIcon();

		ct.slideOut('t', {
			callback : function(){
				this.animating = false;
				Ext.callback(callback);
			},
			scope: this,
			duration: this.node.ownerTree.duration || .25
		});
	},


	getContainer : function(){
		return this.ctNode;
	},


	getEl : function(){
		return this.wrap;
	},


	appendDDGhost : function(ghostNode){
		ghostNode.appendChild(this.elNode.cloneNode(true));
	},


	getDDRepairXY : function(){
		return Ext.lib.Dom.getXY(this.iconNode);
	},


	onRender : function(){
		this.render();
	},


	render : function(bulkRender){
		var n = this.node, a = n.attributes;
		var targetNode = n.parentNode ?
		n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom;

		if(!this.rendered){
			this.rendered = true;

			this.renderElements(n, a, targetNode, bulkRender);

			if(a.qtip){
				this.onTipChange(n, a.qtip, a.qtipTitle);
			}else if(a.qtipCfg){
				a.qtipCfg.target = Ext.id(this.textNode);
				Ext.QuickTips.register(a.qtipCfg);
			}
			this.initEvents();
			if(!this.node.expanded){
				this.updateExpandIcon(true);
			}
		}else{
			if(bulkRender === true) {
				targetNode.appendChild(this.wrap);
			}
		}
	},


	renderElements : function(n, a, targetNode, bulkRender){

		this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';

		var cb = Ext.isBoolean(a.checked),
		nel,
		href = this.getHref(a.href),
		buf = ['<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">',
		'<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
		'<img alt="" src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
		'<img alt="" src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',
		cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
		'<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
		a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
		'<ul class="x-tree-node-ct" style="display:none;"></ul>',
		"</li>"].join('');

		if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
			this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
		}else{
			this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
		}

		this.elNode = this.wrap.childNodes[0];
		this.ctNode = this.wrap.childNodes[1];
		var cs = this.elNode.childNodes;
		this.indentNode = cs[0];
		this.ecNode = cs[1];
		this.iconNode = cs[2];
		var index = 3;
		if(cb){
			this.checkbox = cs[3];

			this.checkbox.defaultChecked = this.checkbox.checked;
			index++;
		}
		this.anchor = cs[index];
		this.textNode = cs[index].firstChild;
	},


	getHref : function(href){
		return Ext.isEmpty(href) ? (Ext.isGecko ? '' : '#') : href;
	},


	getAnchor : function(){
		return this.anchor;
	},


	getTextEl : function(){
		return this.textNode;
	},


	getIconEl : function(){
		return this.iconNode;
	},


	isChecked : function(){
		return this.checkbox ? this.checkbox.checked : false;
	},


	updateExpandIcon : function(){
		if(this.rendered){
			var n = this.node,
			c1,
			c2,
			cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow",
			hasChild = n.hasChildNodes();
			if(hasChild || n.attributes.expandable){
				if(n.expanded){
					cls += "-minus";
					c1 = "x-tree-node-collapsed";
					c2 = "x-tree-node-expanded";
				}else{
					cls += "-plus";
					c1 = "x-tree-node-expanded";
					c2 = "x-tree-node-collapsed";
				}
				if(this.wasLeaf){
					this.removeClass("x-tree-node-leaf");
					this.wasLeaf = false;
				}
				if(this.c1 != c1 || this.c2 != c2){
					Ext.fly(this.elNode).replaceClass(c1, c2);
					this.c1 = c1;
					this.c2 = c2;
				}
			}else{
				if(!this.wasLeaf){
					Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-collapsed");
					delete this.c1;
					delete this.c2;
					this.wasLeaf = true;
				}
			}
			var ecc = "x-tree-ec-icon "+cls;
			if(this.ecc != ecc){
				this.ecNode.className = ecc;
				this.ecc = ecc;
			}
		}
	},


	onIdChange: function(id){
		if(this.rendered){
			this.elNode.setAttribute('ext:tree-node-id', id);
		}
	},


	getChildIndent : function(){
		if(!this.childIndent){
			var buf = [],
			p = this.node;
			while(p){
				if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){
					if(!p.isLast()) {
						buf.unshift('<img alt="" src="'+this.emptyIcon+'" class="x-tree-elbow-line" />');
					} else {
						buf.unshift('<img alt="" src="'+this.emptyIcon+'" class="x-tree-icon" />');
					}
				}
				p = p.parentNode;
			}
			this.childIndent = buf.join("");
		}
		return this.childIndent;
	},


	renderIndent : function(){
		if(this.rendered){
			var indent = "",
			p = this.node.parentNode;
			if(p){
				indent = p.ui.getChildIndent();
			}
			if(this.indentMarkup != indent){
				this.indentNode.innerHTML = indent;
				this.indentMarkup = indent;
			}
			this.updateExpandIcon();
		}
	},

	destroy : function(){
		if(this.elNode){
			Ext.dd.Registry.unregister(this.elNode.id);
		}

		Ext.each(['textnode', 'anchor', 'checkbox', 'indentNode', 'ecNode', 'iconNode', 'elNode', 'ctNode', 'wrap', 'holder'], function(el){
			if(this[el]){
				Ext.fly(this[el]).remove();
				delete this[el];
			}
		}, this);
		delete this.node;
	}
});


Ext.tree.RootTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {

	render : function(){
		if(!this.rendered){
			var targetNode = this.node.ownerTree.innerCt.dom;
			this.node.expanded = true;
			targetNode.innerHTML = '<div class="x-tree-root-node"></div>';
			this.wrap = this.ctNode = targetNode.firstChild;
		}
	},
	collapse : Ext.emptyFn,
	expand : Ext.emptyFn
});
Ext.tree.TreeLoader = function(config){
	this.baseParams = {};
	Ext.apply(this, config);

	this.addEvents(

		"beforeload",

		"load",

		"loadexception"
		);
	Ext.tree.TreeLoader.superclass.constructor.call(this);
	if(Ext.isString(this.paramOrder)){
		this.paramOrder = this.paramOrder.split(/[\s,|]/);
	}
};

Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, {







	uiProviders : {},


	clearOnLoad : true,


	paramOrder: undefined,


	paramsAsHash: false,


	nodeParameter: 'node',


	directFn : undefined,


	load : function(node, callback, scope){
		if(this.clearOnLoad){
			while(node.firstChild){
				node.removeChild(node.firstChild);
			}
		}
		if(this.doPreload(node)){
			this.runCallback(callback, scope || node, [node]);
		}else if(this.directFn || this.dataUrl || this.url){
			this.requestData(node, callback, scope || node);
		}
	},

	doPreload : function(node){
		if(node.attributes.children){
			if(node.childNodes.length < 1){
				var cs = node.attributes.children;
				node.beginUpdate();
				for(var i = 0, len = cs.length; i < len; i++){
					var cn = node.appendChild(this.createNode(cs[i]));
					if(this.preloadChildren){
						this.doPreload(cn);
					}
				}
				node.endUpdate();
			}
			return true;
		}
		return false;
	},

	getParams: function(node){
		var bp = Ext.apply({}, this.baseParams),
		np = this.nodeParameter,
		po = this.paramOrder;

		np && (bp[ np ] = node.id);

		if(this.directFn){
			var buf = [node.id];
			if(po){

				if(np && po.indexOf(np) > -1){
					buf = [];
				}

				for(var i = 0, len = po.length; i < len; i++){
					buf.push(bp[ po[i] ]);
				}
			}else if(this.paramsAsHash){
				buf = [bp];
			}
			return buf;
		}else{
			return bp;
		}
	},

	requestData : function(node, callback, scope){
		if(this.fireEvent("beforeload", this, node, callback) !== false){
			if(this.directFn){
				var args = this.getParams(node);
				args.push(this.processDirectResponse.createDelegate(this, [{
					callback: callback,
					node: node,
					scope: scope
				}], true));
				this.directFn.apply(window, args);
			}else{
				this.transId = Ext.Ajax.request({
					method:this.requestMethod,
					url: this.dataUrl||this.url,
					success: this.handleResponse,
					failure: this.handleFailure,
					scope: this,
					argument: {
						callback: callback,
						node: node,
						scope: scope
					},
					params: this.getParams(node)
				});
			}
		}else{


			this.runCallback(callback, scope || node, []);
		}
	},

	processDirectResponse: function(result, response, args){
		if(response.status){
			this.handleResponse({
				responseData: Ext.isArray(result) ? result : null,
				responseText: result,
				argument: args
			});
		}else{
			this.handleFailure({
				argument: args
			});
		}
	},


	runCallback: function(cb, scope, args){
		if(Ext.isFunction(cb)){
			cb.apply(scope, args);
		}
	},

	isLoading : function(){
		return !!this.transId;
	},

	abort : function(){
		if(this.isLoading()){
			Ext.Ajax.abort(this.transId);
		}
	},


	createNode : function(attr){

		if(this.baseAttrs){
			Ext.applyIf(attr, this.baseAttrs);
		}
		if(this.applyLoader !== false && !attr.loader){
			attr.loader = this;
		}
		if(Ext.isString(attr.uiProvider)){
			attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider);
		}
		if(attr.nodeType){
			return new Ext.tree.TreePanel.nodeTypes[attr.nodeType](attr);
		}else{
			return attr.leaf ?
			new Ext.tree.TreeNode(attr) :
			new Ext.tree.AsyncTreeNode(attr);
		}
	},

	processResponse : function(response, node, callback, scope){
		var json = response.responseText;
		try {
			var o = response.responseData || Ext.decode(json);
			node.beginUpdate();
			for(var i = 0, len = o.length; i < len; i++){
				var n = this.createNode(o[i]);
				if(n){
					node.appendChild(n);
				}
			}
			node.endUpdate();
			this.runCallback(callback, scope || node, [node]);
		}catch(e){
			this.handleFailure(response);
		}
	},

	handleResponse : function(response){
		this.transId = false;
		var a = response.argument;
		this.processResponse(response, a.node, a.callback, a.scope);
		this.fireEvent("load", this, a.node, response);
	},

	handleFailure : function(response){
		this.transId = false;
		var a = response.argument;
		this.fireEvent("loadexception", this, a.node, response);
		this.runCallback(a.callback, a.scope || a.node, [a.node]);
	},

	destroy : function(){
		this.abort();
		this.purgeListeners();
	}
});
Ext.tree.TreeFilter = function(tree, config){
	this.tree = tree;
	this.filtered = {};
	Ext.apply(this, config);
};

Ext.tree.TreeFilter.prototype = {
	clearBlank:false,
	reverse:false,
	autoClear:false,
	remove:false,


	filter : function(value, attr, startNode){
		attr = attr || "text";
		var f;
		if(typeof value == "string"){
			var vlen = value.length;

			if(vlen == 0 && this.clearBlank){
				this.clear();
				return;
			}
			value = value.toLowerCase();
			f = function(n){
				return n.attributes[attr].substr(0, vlen).toLowerCase() == value;
			};
		}else if(value.exec){
			f = function(n){
				return value.test(n.attributes[attr]);
			};
		}else{
			throw 'Illegal filter type, must be string or regex';
		}
		this.filterBy(f, null, startNode);
	},


	filterBy : function(fn, scope, startNode){
		startNode = startNode || this.tree.root;
		if(this.autoClear){
			this.clear();
		}
		var af = this.filtered, rv = this.reverse;
		var f = function(n){
			if(n == startNode){
				return true;
			}
			if(af[n.id]){
				return false;
			}
			var m = fn.call(scope || n, n);
			if(!m || rv){
				af[n.id] = n;
				n.ui.hide();
				return false;
			}
			return true;
		};
		startNode.cascade(f);
		if(this.remove){
			for(var id in af){
				if(typeof id != "function"){
					var n = af[id];
					if(n && n.parentNode){
						n.parentNode.removeChild(n);
					}
				}
			}
		}
	},


	clear : function(){
		var t = this.tree;
		var af = this.filtered;
		for(var id in af){
			if(typeof id != "function"){
				var n = af[id];
				if(n){
					n.ui.show();
				}
			}
		}
		this.filtered = {};
	}
};

Ext.tree.TreeSorter = Ext.extend(Object, {

	constructor: function(tree, config){







		Ext.apply(this, config);
		tree.on({
			scope: this,
			beforechildrenrendered: this.doSort,
			append: this.updateSort,
			insert: this.updateSort,
			textchange: this.updateSortParent
		});

		var desc = this.dir && this.dir.toLowerCase() == 'desc',
		prop = this.property || 'text';
		sortType = this.sortType;
		folderSort = this.folderSort;
		caseSensitive = this.caseSensitive === true;
		leafAttr = this.leafAttr || 'leaf';

		if(Ext.isString(sortType)){
			sortType = Ext.data.SortTypes[sortType];
		}
		this.sortFn = function(n1, n2){
			var attr1 = n1.attributes,
			attr2 = n2.attributes;

			if(folderSort){
				if(attr1[leafAttr] && !attr2[leafAttr]){
					return 1;
				}
				if(!attr1[leafAttr] && attr2[leafAttr]){
					return -1;
				}
			}
			var prop1 = attr1[prop],
			prop2 = attr2[prop],
			v1 = sortType ? sortType(prop1) : (caseSensitive ? prop1 : prop1.toUpperCase());
			v2 = sortType ? sortType(prop2) : (caseSensitive ? prop2 : prop2.toUpperCase());

			if(v1 < v2){
				return desc ? 1 : -1;
			}else if(v1 > v2){
				return desc ? -1 : 1;
			}
			return 0;
		};
	},

	doSort : function(node){
		node.sort(this.sortFn);
	},

	updateSort : function(tree, node){
		if(node.childrenRendered){
			this.doSort.defer(1, this, [node]);
		}
	},

	updateSortParent : function(node){
		var p = node.parentNode;
		if(p && p.childrenRendered){
			this.doSort.defer(1, this, [p]);
		}
	}
});
if(Ext.dd.DropZone){

	Ext.tree.TreeDropZone = function(tree, config){

		this.allowParentInsert = config.allowParentInsert || false;

		this.allowContainerDrop = config.allowContainerDrop || false;

		this.appendOnly = config.appendOnly || false;

		Ext.tree.TreeDropZone.superclass.constructor.call(this, tree.getTreeEl(), config);

		this.tree = tree;

		this.dragOverData = {};

		this.lastInsertClass = "x-tree-no-status";
	};

	Ext.extend(Ext.tree.TreeDropZone, Ext.dd.DropZone, {

		ddGroup : "TreeDD",


		expandDelay : 1000,


		expandNode : function(node){
			if(node.hasChildNodes() && !node.isExpanded()){
				node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
			}
		},


		queueExpand : function(node){
			this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
		},


		cancelExpand : function(){
			if(this.expandProcId){
				clearTimeout(this.expandProcId);
				this.expandProcId = false;
			}
		},


		isValidDropPoint : function(n, pt, dd, e, data){
			if(!n || !data){
				return false;
			}
			var targetNode = n.node;
			var dropNode = data.node;

			if(!(targetNode && targetNode.isTarget && pt)){
				return false;
			}
			if(pt == "append" && targetNode.allowChildren === false){
				return false;
			}
			if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
				return false;
			}
			if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
				return false;
			}

			var overEvent = this.dragOverData;
			overEvent.tree = this.tree;
			overEvent.target = targetNode;
			overEvent.data = data;
			overEvent.point = pt;
			overEvent.source = dd;
			overEvent.rawEvent = e;
			overEvent.dropNode = dropNode;
			overEvent.cancel = false;
			var result = this.tree.fireEvent("nodedragover", overEvent);
			return overEvent.cancel === false && result !== false;
		},


		getDropPoint : function(e, n, dd){
			var tn = n.node;
			if(tn.isRoot){
				return tn.allowChildren !== false ? "append" : false;
			}
			var dragEl = n.ddel;
			var t = Ext.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
			var y = Ext.lib.Event.getPageY(e);
			var noAppend = tn.allowChildren === false || tn.isLeaf();
			if(this.appendOnly || tn.parentNode.allowChildren === false){
				return noAppend ? false : "append";
			}
			var noBelow = false;
			if(!this.allowParentInsert){
				noBelow = tn.hasChildNodes() && tn.isExpanded();
			}
			var q = (b - t) / (noAppend ? 2 : 3);
			if(y >= t && y < (t + q)){
				return "above";
			}else if(!noBelow && (noAppend || y >= b-q && y <= b)){
				return "below";
			}else{
				return "append";
			}
		},


		onNodeEnter : function(n, dd, e, data){
			this.cancelExpand();
		},

		onContainerOver : function(dd, e, data) {
			if (this.allowContainerDrop && this.isValidDropPoint({
				ddel: this.tree.getRootNode().ui.elNode,
				node: this.tree.getRootNode()
			}, "append", dd, e, data)) {
				return this.dropAllowed;
			}
			return this.dropNotAllowed;
		},


		onNodeOver : function(n, dd, e, data){
			var pt = this.getDropPoint(e, n, dd);
			var node = n.node;


			if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
				this.queueExpand(node);
			}else if(pt != "append"){
				this.cancelExpand();
			}


			var returnCls = this.dropNotAllowed;
			if(this.isValidDropPoint(n, pt, dd, e, data)){
				if(pt){
					var el = n.ddel;
					var cls;
					if(pt == "above"){
						returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
						cls = "x-tree-drag-insert-above";
					}else if(pt == "below"){
						returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
						cls = "x-tree-drag-insert-below";
					}else{
						returnCls = "x-tree-drop-ok-append";
						cls = "x-tree-drag-append";
					}
					if(this.lastInsertClass != cls){
						Ext.fly(el).replaceClass(this.lastInsertClass, cls);
						this.lastInsertClass = cls;
					}
				}
			}
			return returnCls;
		},


		onNodeOut : function(n, dd, e, data){
			this.cancelExpand();
			this.removeDropIndicators(n);
		},


		onNodeDrop : function(n, dd, e, data){
			var point = this.getDropPoint(e, n, dd);
			var targetNode = n.node;
			targetNode.ui.startDrop();
			if(!this.isValidDropPoint(n, point, dd, e, data)){
				targetNode.ui.endDrop();
				return false;
			}

			var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
			return this.processDrop(targetNode, data, point, dd, e, dropNode);
		},

		onContainerDrop : function(dd, e, data){
			if (this.allowContainerDrop && this.isValidDropPoint({
				ddel: this.tree.getRootNode().ui.elNode,
				node: this.tree.getRootNode()
			}, "append", dd, e, data)) {
				var targetNode = this.tree.getRootNode();
				targetNode.ui.startDrop();
				var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, 'append', e) : null);
				return this.processDrop(targetNode, data, 'append', dd, e, dropNode);
			}
			return false;
		},


		processDrop: function(target, data, point, dd, e, dropNode){
			var dropEvent = {
				tree : this.tree,
				target: target,
				data: data,
				point: point,
				source: dd,
				rawEvent: e,
				dropNode: dropNode,
				cancel: !dropNode,
				dropStatus: false
			};
			var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
			if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
				target.ui.endDrop();
				return dropEvent.dropStatus;
			}

			target = dropEvent.target;
			if(point == 'append' && !target.isExpanded()){
				target.expand(false, null, function(){
					this.completeDrop(dropEvent);
				}.createDelegate(this));
			}else{
				this.completeDrop(dropEvent);
			}
			return true;
		},


		completeDrop : function(de){
			var ns = de.dropNode, p = de.point, t = de.target;
			if(!Ext.isArray(ns)){
				ns = [ns];
			}
			var n;
			for(var i = 0, len = ns.length; i < len; i++){
				n = ns[i];
				if(p == "above"){
					t.parentNode.insertBefore(n, t);
				}else if(p == "below"){
					t.parentNode.insertBefore(n, t.nextSibling);
				}else{
					t.appendChild(n);
				}
			}
			n.ui.focus();
			if(Ext.enableFx && this.tree.hlDrop){
				n.ui.highlight();
			}
			t.ui.endDrop();
			this.tree.fireEvent("nodedrop", de);
		},


		afterNodeMoved : function(dd, data, e, targetNode, dropNode){
			if(Ext.enableFx && this.tree.hlDrop){
				dropNode.ui.focus();
				dropNode.ui.highlight();
			}
			this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e);
		},


		getTree : function(){
			return this.tree;
		},


		removeDropIndicators : function(n){
			if(n && n.ddel){
				var el = n.ddel;
				Ext.fly(el).removeClass([
					"x-tree-drag-insert-above",
					"x-tree-drag-insert-below",
					"x-tree-drag-append"]);
				this.lastInsertClass = "_noclass";
			}
		},


		beforeDragDrop : function(target, e, id){
			this.cancelExpand();
			return true;
		},


		afterRepair : function(data){
			if(data && Ext.enableFx){
				data.node.ui.highlight();
			}
			this.hideProxy();
		}
	});

}
if(Ext.dd.DragZone){
	Ext.tree.TreeDragZone = function(tree, config){
		Ext.tree.TreeDragZone.superclass.constructor.call(this, tree.innerCt, config);

		this.tree = tree;
	};

	Ext.extend(Ext.tree.TreeDragZone, Ext.dd.DragZone, {

		ddGroup : "TreeDD",


		onBeforeDrag : function(data, e){
			var n = data.node;
			return n && n.draggable && !n.disabled;
		},


		onInitDrag : function(e){
			var data = this.dragData;
			this.tree.getSelectionModel().select(data.node);
			this.tree.eventModel.disable();
			this.proxy.update("");
			data.node.ui.appendDDGhost(this.proxy.ghost.dom);
			this.tree.fireEvent("startdrag", this.tree, data.node, e);
		},


		getRepairXY : function(e, data){
			return data.node.ui.getDDRepairXY();
		},


		onEndDrag : function(data, e){
			this.tree.eventModel.enable.defer(100, this.tree.eventModel);
			this.tree.fireEvent("enddrag", this.tree, data.node, e);
		},


		onValidDrop : function(dd, e, id){
			this.tree.fireEvent("dragdrop", this.tree, this.dragData.node, dd, e);
			this.hideProxy();
		},


		beforeInvalidDrop : function(e, id){

			var sm = this.tree.getSelectionModel();
			sm.clearSelections();
			sm.select(this.dragData.node);
		},


		afterRepair : function(){
			if (Ext.enableFx && this.tree.hlDrop) {
				Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
			}
			this.dragging = false;
		}
	});
}
Ext.tree.TreeEditor = function(tree, fc, config){
	fc = fc || {};
	var field = fc.events ? fc : new Ext.form.TextField(fc);

	Ext.tree.TreeEditor.superclass.constructor.call(this, field, config);

	this.tree = tree;

	if(!tree.rendered){
		tree.on('render', this.initEditor, this);
	}else{
		this.initEditor(tree);
	}
};

Ext.extend(Ext.tree.TreeEditor, Ext.Editor, {

	alignment: "l-l",

	autoSize: false,

	hideEl : false,

	cls: "x-small-editor x-tree-editor",

	shim:false,

	shadow:"frame",

	maxWidth: 250,

	editDelay : 350,

	initEditor : function(tree){
		tree.on({
			scope      : this,
			beforeclick: this.beforeNodeClick,
			dblclick   : this.onNodeDblClick
		});

		this.on({
			scope          : this,
			complete       : this.updateNode,
			beforestartedit: this.fitToTree,
			specialkey     : this.onSpecialKey
		});

		this.on('startedit', this.bindScroll, this, {
			delay:10
		});
	},


	fitToTree : function(ed, el){
		var td = this.tree.getTreeEl().dom, nd = el.dom;
		if(td.scrollLeft >  nd.offsetLeft){
			td.scrollLeft = nd.offsetLeft;
		}
		var w = Math.min(
			this.maxWidth,
			(td.clientWidth > 20 ? td.clientWidth : td.offsetWidth) - Math.max(0, nd.offsetLeft-td.scrollLeft) - 5);
		this.setSize(w, '');
	},


	triggerEdit : function(node, defer){
		this.completeEdit();
		if(node.attributes.editable !== false){

			this.editNode = node;
			if(this.tree.autoScroll){
				Ext.fly(node.ui.getEl()).scrollIntoView(this.tree.body);
			}
			var value = node.text || '';
			if (!Ext.isGecko && Ext.isEmpty(node.text)){
				node.setText('&#160;');
			}
			this.autoEditTimer = this.startEdit.defer(this.editDelay, this, [node.ui.textNode, value]);
			return false;
		}
	},


	bindScroll : function(){
		this.tree.getTreeEl().on('scroll', this.cancelEdit, this);
	},


	beforeNodeClick : function(node, e){
		clearTimeout(this.autoEditTimer);
		if(this.tree.getSelectionModel().isSelected(node)){
			e.stopEvent();
			return this.triggerEdit(node);
		}
	},

	onNodeDblClick : function(node, e){
		clearTimeout(this.autoEditTimer);
	},


	updateNode : function(ed, value){
		this.tree.getTreeEl().un('scroll', this.cancelEdit, this);
		this.editNode.setText(value);
	},


	onHide : function(){
		Ext.tree.TreeEditor.superclass.onHide.call(this);
		if(this.editNode){
			this.editNode.ui.focus.defer(50, this.editNode.ui);
		}
	},


	onSpecialKey : function(field, e){
		var k = e.getKey();
		if(k == e.ESC){
			e.stopEvent();
			this.cancelEdit();
		}else if(k == e.ENTER && !e.hasModifier()){
			e.stopEvent();
			this.completeEdit();
		}
	},

	onDestroy : function(){
		clearTimeout(this.autoEditTimer);
		Ext.tree.TreeEditor.superclass.onDestroy.call(this);
		var tree = this.tree;
		tree.un('beforeclick', this.beforeNodeClick, this);
		tree.un('dblclick', this.onNodeDblClick, this);
	}
});

var swfobject = function() {

	var UNDEF = "undefined",
	OBJECT = "object",
	SHOCKWAVE_FLASH = "Shockwave Flash",
	SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
	FLASH_MIME_TYPE = "application/x-shockwave-flash",
	EXPRESS_INSTALL_ID = "SWFObjectExprInst",
	ON_READY_STATE_CHANGE = "onreadystatechange",

	win = window,
	doc = document,
	nav = navigator,

	plugin = false,
	domLoadFnArr = [main],
	regObjArr = [],
	objIdArr = [],
	listenersArr = [],
	storedAltContent,
	storedAltContentId,
	storedCallbackFn,
	storedCallbackObj,
	isDomLoaded = false,
	isExpressInstallActive = false,
	dynamicStylesheet,
	dynamicStylesheetMedia,
	autoHideShow = true,


	ua = function() {
		var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
		u = nav.userAgent.toLowerCase(),
		p = nav.platform.toLowerCase(),
		windows = p ? (/win/).test(p) : /win/.test(u),
		mac = p ? (/mac/).test(p) : /mac/.test(u),
		webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false,
		ie = !+"\v1",
		playerVersion = [0,0,0],
		d = null;
		if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {
			d = nav.plugins[SHOCKWAVE_FLASH].description;
			if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) {
				plugin = true;
				ie = false;
				d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
				playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
				playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
				playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0;
			}
		}
		else if (typeof win.ActiveXObject != UNDEF) {
			try {
				var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);
				if (a) {
					d = a.GetVariable("$version");
					if (d) {
						ie = true;
						d = d.split(" ")[1].split(",");
						playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
					}
				}
			}
			catch(e) {}
		}
		return {
			w3:w3cdom,
			pv:playerVersion,
			wk:webkit,
			ie:ie,
			win:windows,
			mac:mac
		};
	}(),


	onDomLoad = function() {
		if (!ua.w3) {
			return;
		}
		if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) {
			callDomLoadFunctions();
		}
		if (!isDomLoaded) {
			if (typeof doc.addEventListener != UNDEF) {
				doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false);
			}
			if (ua.ie && ua.win) {
				doc.attachEvent(ON_READY_STATE_CHANGE, function() {
					if (doc.readyState == "complete") {
						doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee);
						callDomLoadFunctions();
					}
				});
				if (win == top) {
					(function(){
						if (isDomLoaded) {
							return;
						}
						try {
							doc.documentElement.doScroll("left");
						}
						catch(e) {
							setTimeout(arguments.callee, 0);
							return;
						}
						callDomLoadFunctions();
					})();
				}
			}
			if (ua.wk) {
				(function(){
					if (isDomLoaded) {
						return;
					}
					if (!(/loaded|complete/).test(doc.readyState)) {
						setTimeout(arguments.callee, 0);
						return;
					}
					callDomLoadFunctions();
				})();
			}
			addLoadEvent(callDomLoadFunctions);
		}
	}();

	function callDomLoadFunctions() {
		if (isDomLoaded) {
			return;
		}
		try {
			var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span"));
			t.parentNode.removeChild(t);
		}
		catch (e) {
			return;
		}
		isDomLoaded = true;
		var dl = domLoadFnArr.length;
		for (var i = 0; i < dl; i++) {
			domLoadFnArr[i]();
		}
	}

	function addDomLoadEvent(fn) {
		if (isDomLoaded) {
			fn();
		}
		else {
			domLoadFnArr[domLoadFnArr.length] = fn;
		}
	}


	function addLoadEvent(fn) {
		if (typeof win.addEventListener != UNDEF) {
			win.addEventListener("load", fn, false);
		}
		else if (typeof doc.addEventListener != UNDEF) {
			doc.addEventListener("load", fn, false);
		}
		else if (typeof win.attachEvent != UNDEF) {
			addListener(win, "onload", fn);
		}
		else if (typeof win.onload == "function") {
			var fnOld = win.onload;
			win.onload = function() {
				fnOld();
				fn();
			};
		}
		else {
			win.onload = fn;
		}
	}


	function main() {
		if (plugin) {
			testPlayerVersion();
		}
		else {
			matchVersions();
		}
	}


	function testPlayerVersion() {
		var b = doc.getElementsByTagName("body")[0];
		var o = createElement(OBJECT);
		o.setAttribute("type", FLASH_MIME_TYPE);
		var t = b.appendChild(o);
		if (t) {
			var counter = 0;
			(function(){
				if (typeof t.GetVariable != UNDEF) {
					var d = t.GetVariable("$version");
					if (d) {
						d = d.split(" ")[1].split(",");
						ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
					}
				}
				else if (counter < 10) {
					counter++;
					setTimeout(arguments.callee, 10);
					return;
				}
				b.removeChild(o);
				t = null;
				matchVersions();
			})();
		}
		else {
			matchVersions();
		}
	}


	function matchVersions() {
		var rl = regObjArr.length;
		if (rl > 0) {
			for (var i = 0; i < rl; i++) {
				var id = regObjArr[i].id;
				var cb = regObjArr[i].callbackFn;
				var cbObj = {
					success:false,
					id:id
				};
				if (ua.pv[0] > 0) {
					var obj = getElementById(id);
					if (obj) {
						if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) {
							setVisibility(id, true);
							if (cb) {
								cbObj.success = true;
								cbObj.ref = getObjectById(id);
								cb(cbObj);
							}
						}
						else if (regObjArr[i].expressInstall && canExpressInstall()) {
							var att = {};
							att.data = regObjArr[i].expressInstall;
							att.width = obj.getAttribute("width") || "0";
							att.height = obj.getAttribute("height") || "0";
							if (obj.getAttribute("class")) {
								att.styleclass = obj.getAttribute("class");
							}
							if (obj.getAttribute("align")) {
								att.align = obj.getAttribute("align");
							}

							var par = {};
							var p = obj.getElementsByTagName("param");
							var pl = p.length;
							for (var j = 0; j < pl; j++) {
								if (p[j].getAttribute("name").toLowerCase() != "movie") {
									par[p[j].getAttribute("name")] = p[j].getAttribute("value");
								}
							}
							showExpressInstall(att, par, id, cb);
						}
						else {
							displayAltContent(obj);
							if (cb) {
								cb(cbObj);
							}
						}
					}
				}
				else {
					setVisibility(id, true);
					if (cb) {
						var o = getObjectById(id);
						if (o && typeof o.SetVariable != UNDEF) {
							cbObj.success = true;
							cbObj.ref = o;
						}
						cb(cbObj);
					}
				}
			}
		}
	}

	function getObjectById(objectIdStr) {
		var r = null;
		var o = getElementById(objectIdStr);
		if (o && o.nodeName == "OBJECT") {
			if (typeof o.SetVariable != UNDEF) {
				r = o;
			}
			else {
				var n = o.getElementsByTagName(OBJECT)[0];
				if (n) {
					r = n;
				}
			}
		}
		return r;
	}


	function canExpressInstall() {
		return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);
	}


	function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {
		isExpressInstallActive = true;
		storedCallbackFn = callbackFn || null;
		storedCallbackObj = {
			success:false,
			id:replaceElemIdStr
		};
		var obj = getElementById(replaceElemIdStr);
		if (obj) {
			if (obj.nodeName == "OBJECT") {
				storedAltContent = abstractAltContent(obj);
				storedAltContentId = null;
			}
			else {
				storedAltContent = obj;
				storedAltContentId = replaceElemIdStr;
			}
			att.id = EXPRESS_INSTALL_ID;
			if (typeof att.width == UNDEF || (!(/%$/).test(att.width) && parseInt(att.width, 10) < 310)) {
				att.width = "310";
			}

			if (typeof att.height == UNDEF || (!(/%$/).test(att.height) && parseInt(att.height, 10) < 137)) {
				att.height = "137";
			}
			doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
			var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
			fv = "MMredirectURL=" + win.location.toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title;
			if (typeof par.flashvars != UNDEF) {
				par.flashvars += "&" + fv;
			}
			else {
				par.flashvars = fv;
			}


			if (ua.ie && ua.win && obj.readyState != 4) {
				var newObj = createElement("div");
				replaceElemIdStr += "SWFObjectNew";
				newObj.setAttribute("id", replaceElemIdStr);
				obj.parentNode.insertBefore(newObj, obj);
				obj.style.display = "none";
				(function(){
					if (obj.readyState == 4) {
						obj.parentNode.removeChild(obj);
					}
					else {
						setTimeout(arguments.callee, 10);
					}
				})();
			}
			createSWF(att, par, replaceElemIdStr);
		}
	}


	function displayAltContent(obj) {
		if (ua.ie && ua.win && obj.readyState != 4) {


			var el = createElement("div");
			obj.parentNode.insertBefore(el, obj);
			el.parentNode.replaceChild(abstractAltContent(obj), el);
			obj.style.display = "none";
			(function(){
				if (obj.readyState == 4) {
					obj.parentNode.removeChild(obj);
				}
				else {
					setTimeout(arguments.callee, 10);
				}
			})();
		}
		else {
			obj.parentNode.replaceChild(abstractAltContent(obj), obj);
		}
	}

	function abstractAltContent(obj) {
		var ac = createElement("div");
		if (ua.win && ua.ie) {
			ac.innerHTML = obj.innerHTML;
		}
		else {
			var nestedObj = obj.getElementsByTagName(OBJECT)[0];
			if (nestedObj) {
				var c = nestedObj.childNodes;
				if (c) {
					var cl = c.length;
					for (var i = 0; i < cl; i++) {
						if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) {
							ac.appendChild(c[i].cloneNode(true));
						}
					}
				}
			}
		}
		return ac;
	}


	function createSWF(attObj, parObj, id) {
		var r, el = getElementById(id);
		if (ua.wk && ua.wk < 312) {
			return r;
		}
		if (el) {
			if (typeof attObj.id == UNDEF) {
				attObj.id = id;
			}
			if (ua.ie && ua.win) {
				var att = "";
				for (var i in attObj) {
					if (attObj[i] != Object.prototype[i]) {
						if (i.toLowerCase() == "data") {
							parObj.movie = attObj[i];
						}
						else if (i.toLowerCase() == "styleclass") {
							att += ' class="' + attObj[i] + '"';
						}
						else if (i.toLowerCase() != "classid") {
							att += ' ' + i + '="' + attObj[i] + '"';
						}
					}
				}
				var par = "";
				for (var j in parObj) {
					if (parObj[j] != Object.prototype[j]) {
						par += '<param name="' + j + '" value="' + parObj[j] + '" />';
					}
				}
				el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>';
				objIdArr[objIdArr.length] = attObj.id;
				r = getElementById(attObj.id);
			}
			else {
				var o = createElement(OBJECT);
				o.setAttribute("type", FLASH_MIME_TYPE);
				for (var m in attObj) {
					if (attObj[m] != Object.prototype[m]) {
						if (m.toLowerCase() == "styleclass") {
							o.setAttribute("class", attObj[m]);
						}
						else if (m.toLowerCase() != "classid") {
							o.setAttribute(m, attObj[m]);
						}
					}
				}
				for (var n in parObj) {
					if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") {
						createObjParam(o, n, parObj[n]);
					}
				}
				el.parentNode.replaceChild(o, el);
				r = o;
			}
		}
		return r;
	}

	function createObjParam(el, pName, pValue) {
		var p = createElement("param");
		p.setAttribute("name", pName);
		p.setAttribute("value", pValue);
		el.appendChild(p);
	}


	function removeSWF(id) {
		var obj = getElementById(id);
		if (obj && obj.nodeName == "OBJECT") {
			if (ua.ie && ua.win) {
				obj.style.display = "none";
				(function(){
					if (obj.readyState == 4) {
						removeObjectInIE(id);
					}
					else {
						setTimeout(arguments.callee, 10);
					}
				})();
			}
			else {
				obj.parentNode.removeChild(obj);
			}
		}
	}

	function removeObjectInIE(id) {
		var obj = getElementById(id);
		if (obj) {
			for (var i in obj) {
				if (typeof obj[i] == "function") {
					obj[i] = null;
				}
			}
			obj.parentNode.removeChild(obj);
		}
	}


	function getElementById(id) {
		var el = null;
		try {
			el = doc.getElementById(id);
		}
		catch (e) {}
		return el;
	}

	function createElement(el) {
		return doc.createElement(el);
	}


	function addListener(target, eventType, fn) {
		target.attachEvent(eventType, fn);
		listenersArr[listenersArr.length] = [target, eventType, fn];
	}


	function hasPlayerVersion(rv) {
		var pv = ua.pv, v = rv.split(".");
		v[0] = parseInt(v[0], 10);
		v[1] = parseInt(v[1], 10) || 0;
		v[2] = parseInt(v[2], 10) || 0;
		return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false;
	}


	function createCSS(sel, decl, media, newStyle) {
		if (ua.ie && ua.mac) {
			return;
		}
		var h = doc.getElementsByTagName("head")[0];
		if (!h) {
			return;
		}
		var m = (media && typeof media == "string") ? media : "screen";
		if (newStyle) {
			dynamicStylesheet = null;
			dynamicStylesheetMedia = null;
		}
		if (!dynamicStylesheet || dynamicStylesheetMedia != m) {

			var s = createElement("style");
			s.setAttribute("type", "text/css");
			s.setAttribute("media", m);
			dynamicStylesheet = h.appendChild(s);
			if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {
				dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];
			}
			dynamicStylesheetMedia = m;
		}

		if (ua.ie && ua.win) {
			if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) {
				dynamicStylesheet.addRule(sel, decl);
			}
		}
		else {
			if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) {
				dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}"));
			}
		}
	}

	function setVisibility(id, isVisible) {
		if (!autoHideShow) {
			return;
		}
		var v = isVisible ? "visible" : "hidden";
		if (isDomLoaded && getElementById(id)) {
			getElementById(id).style.visibility = v;
		}
		else {
			createCSS("#" + id, "visibility:" + v);
		}
	}


	function urlEncodeIfNecessary(s) {
		var regex = /[\\\"<>\.;]/;
		var hasBadChars = regex.exec(s) != null;
		return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s;
	}


	var cleanup = function() {
		if (ua.ie && ua.win) {
			window.attachEvent("onunload", function() {

				var ll = listenersArr.length;
				for (var i = 0; i < ll; i++) {
					listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);
				}

				var il = objIdArr.length;
				for (var j = 0; j < il; j++) {
					removeSWF(objIdArr[j]);
				}

				for (var k in ua) {
					ua[k] = null;
				}
				ua = null;
				for (var l in swfobject) {
					swfobject[l] = null;
				}
				swfobject = null;
			});
		}
	}();

	return {

		registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {
			if (ua.w3 && objectIdStr && swfVersionStr) {
				var regObj = {};
				regObj.id = objectIdStr;
				regObj.swfVersion = swfVersionStr;
				regObj.expressInstall = xiSwfUrlStr;
				regObj.callbackFn = callbackFn;
				regObjArr[regObjArr.length] = regObj;
				setVisibility(objectIdStr, false);
			}
			else if (callbackFn) {
				callbackFn({
					success:false,
					id:objectIdStr
				});
			}
		},

		getObjectById: function(objectIdStr) {
			if (ua.w3) {
				return getObjectById(objectIdStr);
			}
		},

		embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
			var callbackObj = {
				success:false,
				id:replaceElemIdStr
			};
			if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {
				setVisibility(replaceElemIdStr, false);
				addDomLoadEvent(function() {
					widthStr += "";
					heightStr += "";
					var att = {};
					if (attObj && typeof attObj === OBJECT) {
						for (var i in attObj) {
							att[i] = attObj[i];
						}
					}
					att.data = swfUrlStr;
					att.width = widthStr;
					att.height = heightStr;
					var par = {};
					if (parObj && typeof parObj === OBJECT) {
						for (var j in parObj) {
							par[j] = parObj[j];
						}
					}
					if (flashvarsObj && typeof flashvarsObj === OBJECT) {
						for (var k in flashvarsObj) {
							if (typeof par.flashvars != UNDEF) {
								par.flashvars += "&" + k + "=" + flashvarsObj[k];
							}
							else {
								par.flashvars = k + "=" + flashvarsObj[k];
							}
						}
					}
					if (hasPlayerVersion(swfVersionStr)) {
						var obj = createSWF(att, par, replaceElemIdStr);
						if (att.id == replaceElemIdStr) {
							setVisibility(replaceElemIdStr, true);
						}
						callbackObj.success = true;
						callbackObj.ref = obj;
					}
					else if (xiSwfUrlStr && canExpressInstall()) {
						att.data = xiSwfUrlStr;
						showExpressInstall(att, par, replaceElemIdStr, callbackFn);
						return;
					}
					else {
						setVisibility(replaceElemIdStr, true);
					}
					if (callbackFn) {
						callbackFn(callbackObj);
					}
				});
			}
			else if (callbackFn) {
				callbackFn(callbackObj);
			}
		},

		switchOffAutoHideShow: function() {
			autoHideShow = false;
		},

		ua: ua,

		getFlashPlayerVersion: function() {
			return {
				major:ua.pv[0],
				minor:ua.pv[1],
				release:ua.pv[2]
			};
		},

		hasFlashPlayerVersion: hasPlayerVersion,

		createSWF: function(attObj, parObj, replaceElemIdStr) {
			if (ua.w3) {
				return createSWF(attObj, parObj, replaceElemIdStr);
			}
			else {
				return undefined;
			}
		},

		showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) {
			if (ua.w3 && canExpressInstall()) {
				showExpressInstall(att, par, replaceElemIdStr, callbackFn);
			}
		},

		removeSWF: function(objElemIdStr) {
			if (ua.w3) {
				removeSWF(objElemIdStr);
			}
		},

		createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) {
			if (ua.w3) {
				createCSS(selStr, declStr, mediaStr, newStyleBoolean);
			}
		},

		addDomLoadEvent: addDomLoadEvent,

		addLoadEvent: addLoadEvent,

		getQueryParamValue: function(param) {
			var q = doc.location.search || doc.location.hash;
			if (q) {
				if (/\?/.test(q)) {
					q = q.split("?")[1];
				}
				if (param == null) {
					return urlEncodeIfNecessary(q);
				}
				var pairs = q.split("&");
				for (var i = 0; i < pairs.length; i++) {
					if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
						return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1)));
					}
				}
			}
			return "";
		},


		expressInstallCallback: function() {
			if (isExpressInstallActive) {
				var obj = getElementById(EXPRESS_INSTALL_ID);
				if (obj && storedAltContent) {
					obj.parentNode.replaceChild(storedAltContent, obj);
					if (storedAltContentId) {
						setVisibility(storedAltContentId, true);
						if (ua.ie && ua.win) {
							storedAltContent.style.display = "block";
						}
					}
					if (storedCallbackFn) {
						storedCallbackFn(storedCallbackObj);
					}
				}
				isExpressInstallActive = false;
			}
		}
	};
}();

Ext.FlashComponent = Ext.extend(Ext.BoxComponent, {

	flashVersion : '9.0.115',


	backgroundColor: '#ffffff',


	wmode: 'opaque',


	flashVars: undefined,


	flashParams: undefined,


	url: undefined,
	swfId : undefined,
	swfWidth: '100%',
	swfHeight: '100%',


	expressInstall: false,

	initComponent : function(){
		Ext.FlashComponent.superclass.initComponent.call(this);

		this.addEvents(

			'initialize'
			);
	},

	onRender : function(){
		Ext.FlashComponent.superclass.onRender.apply(this, arguments);

		var params = Ext.apply({
			allowScriptAccess: 'always',
			bgcolor: this.backgroundColor,
			wmode: this.wmode
		}, this.flashParams), vars = Ext.apply({
			allowedDomain: document.location.hostname,
			YUISwfId: this.getId(),
			YUIBridgeCallback: 'Ext.FlashEventProxy.onEvent'
		}, this.flashVars);

		new swfobject.embedSWF(this.url, this.id, this.swfWidth, this.swfHeight, this.flashVersion,
			this.expressInstall ? Ext.FlashComponent.EXPRESS_INSTALL_URL : undefined, vars, params);

		this.swf = Ext.getDom(this.id);
		this.el = Ext.get(this.swf);
	},

	getSwfId : function(){
		return this.swfId || (this.swfId = "extswf" + (++Ext.Component.AUTO_ID));
	},

	getId : function(){
		return this.id || (this.id = "extflashcmp" + (++Ext.Component.AUTO_ID));
	},

	onFlashEvent : function(e){
		switch(e.type){
			case "swfReady":
				this.initSwf();
				return;
			case "log":
				return;
		}
		e.component = this;
		this.fireEvent(e.type.toLowerCase().replace(/event$/, ''), e);
	},

	initSwf : function(){
		this.onSwfReady(!!this.isInitialized);
		this.isInitialized = true;
		this.fireEvent('initialize', this);
	},

	beforeDestroy: function(){
		if(this.rendered){
			swfobject.removeSWF(this.swf.id);
		}
		Ext.FlashComponent.superclass.beforeDestroy.call(this);
	},

	onSwfReady : Ext.emptyFn
});


Ext.FlashComponent.EXPRESS_INSTALL_URL = 'http:/' + '/swfobject.googlecode.com/svn/trunk/swfobject/expressInstall.swf';

Ext.reg('flash', Ext.FlashComponent);
Ext.FlashEventProxy = {
	onEvent : function(id, e){
		var fp = Ext.getCmp(id);
		if(fp){
			fp.onFlashEvent(e);
		}else{
			arguments.callee.defer(10, this, [id, e]);
		}
	}
};

Ext.chart.Chart = Ext.extend(Ext.FlashComponent, {
	refreshBuffer: 100,




	chartStyle: {
		padding: 10,
		animationEnabled: true,
		font: {
			name: 'Tahoma',
			color: 0x444444,
			size: 11
		},
		dataTip: {
			padding: 5,
			border: {
				color: 0x99bbe8,
				size:1
			},
			background: {
				color: 0xDAE7F6,
				alpha: .9
			},
			font: {
				name: 'Tahoma',
				color: 0x15428B,
				size: 10,
				bold: true
			}
		}
	},




	extraStyle: null,


	seriesStyles: null,


	disableCaching: Ext.isIE || Ext.isOpera,
	disableCacheParam: '_dc',

	initComponent : function(){
		Ext.chart.Chart.superclass.initComponent.call(this);
		if(!this.url){
			this.url = Ext.chart.Chart.CHART_URL;
		}
		if(this.disableCaching){
			this.url = Ext.urlAppend(this.url, String.format('{0}={1}', this.disableCacheParam, new Date().getTime()));
		}
		this.addEvents(
			'itemmouseover',
			'itemmouseout',
			'itemclick',
			'itemdoubleclick',
			'itemdragstart',
			'itemdrag',
			'itemdragend',

			'beforerefresh',

			'refresh'
			);
		this.store = Ext.StoreMgr.lookup(this.store);
	},


	setStyle: function(name, value){
		this.swf.setStyle(name, Ext.encode(value));
	},


	setStyles: function(styles){
		this.swf.setStyles(Ext.encode(styles));
	},


	setSeriesStyles: function(styles){
		this.seriesStyles = styles;
		var s = [];
		Ext.each(styles, function(style){
			s.push(Ext.encode(style));
		});
		this.swf.setSeriesStyles(s);
	},

	setCategoryNames : function(names){
		this.swf.setCategoryNames(names);
	},

	setLegendRenderer : function(fn, scope){
		var chart = this;
		scope = scope || chart;
		chart.removeFnProxy(chart.legendFnName);
		chart.legendFnName = chart.createFnProxy(function(name){
			return fn.call(scope, name);
		});
		chart.swf.setLegendLabelFunction(chart.legendFnName);
	},

	setTipRenderer : function(fn, scope){
		var chart = this;
		scope = scope || chart;
		chart.removeFnProxy(chart.tipFnName);
		chart.tipFnName = chart.createFnProxy(function(item, index, series){
			var record = chart.store.getAt(index);
			return fn.call(scope, chart, record, index, series);
		});
		chart.swf.setDataTipFunction(chart.tipFnName);
	},

	setSeries : function(series){
		this.series = series;
		this.refresh();
	},


	bindStore : function(store, initial){
		if(!initial && this.store){
			if(store !== this.store && this.store.autoDestroy){
				this.store.destroy();
			}else{
				this.store.un("datachanged", this.refresh, this);
				this.store.un("add", this.delayRefresh, this);
				this.store.un("remove", this.delayRefresh, this);
				this.store.un("update", this.delayRefresh, this);
				this.store.un("clear", this.refresh, this);
			}
		}
		if(store){
			store = Ext.StoreMgr.lookup(store);
			store.on({
				scope: this,
				datachanged: this.refresh,
				add: this.delayRefresh,
				remove: this.delayRefresh,
				update: this.delayRefresh,
				clear: this.refresh
			});
		}
		this.store = store;
		if(store && !initial){
			this.refresh();
		}
	},

	onSwfReady : function(isReset){
		Ext.chart.Chart.superclass.onSwfReady.call(this, isReset);
		var ref;
		this.swf.setType(this.type);

		if(this.chartStyle){
			this.setStyles(Ext.apply({}, this.extraStyle, this.chartStyle));
		}

		if(this.categoryNames){
			this.setCategoryNames(this.categoryNames);
		}

		if(this.tipRenderer){
			ref = this.getFunctionRef(this.tipRenderer);
			this.setTipRenderer(ref.fn, ref.scope);
		}
		if(this.legendRenderer){
			ref = this.getFunctionRef(this.legendRenderer);
			this.setLegendRenderer(ref.fn, ref.scope);
		}
		if(!isReset){
			this.bindStore(this.store, true);
		}
		this.refresh.defer(10, this);
	},

	delayRefresh : function(){
		if(!this.refreshTask){
			this.refreshTask = new Ext.util.DelayedTask(this.refresh, this);
		}
		this.refreshTask.delay(this.refreshBuffer);
	},

	refresh : function(){
		if(this.fireEvent('beforerefresh', this) !== false){
			var styleChanged = false;

			var data = [], rs = this.store.data.items;
			for(var j = 0, len = rs.length; j < len; j++){
				data[j] = rs[j].data;
			}


			var dataProvider = [];
			var seriesCount = 0;
			var currentSeries = null;
			var i = 0;
			if(this.series){
				seriesCount = this.series.length;
				for(i = 0; i < seriesCount; i++){
					currentSeries = this.series[i];
					var clonedSeries = {};
					for(var prop in currentSeries){
						if(prop == "style" && currentSeries.style !== null){
							clonedSeries.style = Ext.encode(currentSeries.style);
							styleChanged = true;




						} else{
							clonedSeries[prop] = currentSeries[prop];
						}
					}
					dataProvider.push(clonedSeries);
				}
			}

			if(seriesCount > 0){
				for(i = 0; i < seriesCount; i++){
					currentSeries = dataProvider[i];
					if(!currentSeries.type){
						currentSeries.type = this.type;
					}
					currentSeries.dataProvider = data;
				}
			} else{
				dataProvider.push({
					type: this.type,
					dataProvider: data
				});
			}
			this.swf.setDataProvider(dataProvider);
			if(this.seriesStyles){
				this.setSeriesStyles(this.seriesStyles);
			}
			this.fireEvent('refresh', this);
		}
	},


	createFnProxy : function(fn){
		var fnName = 'extFnProxy' + (++Ext.chart.Chart.PROXY_FN_ID);
		Ext.chart.Chart.proxyFunction[fnName] = fn;
		return 'Ext.chart.Chart.proxyFunction.' + fnName;
	},


	removeFnProxy : function(fn){
		if(!Ext.isEmpty(fn)){
			fn = fn.replace('Ext.chart.Chart.proxyFunction.', '');
			delete Ext.chart.Chart.proxyFunction[fn];
		}
	},


	getFunctionRef : function(val){
		if(Ext.isFunction(val)){
			return {
				fn: val,
				scope: this
			};
		}else{
			return {
				fn: val.fn,
				scope: val.scope || this
			};
		}
	},


	onDestroy: function(){
		if (this.refreshTask && this.refreshTask.cancel){
			this.refreshTask.cancel();
		}
		Ext.chart.Chart.superclass.onDestroy.call(this);
		this.bindStore(null);
		this.removeFnProxy(this.tipFnName);
		this.removeFnProxy(this.legendFnName);
	}
});
Ext.reg('chart', Ext.chart.Chart);
Ext.chart.Chart.PROXY_FN_ID = 0;
Ext.chart.Chart.proxyFunction = {};


Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.8.2/build/charts/assets/charts.swf';


Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, {
	type: 'pie',

	onSwfReady : function(isReset){
		Ext.chart.PieChart.superclass.onSwfReady.call(this, isReset);

		this.setDataField(this.dataField);
		this.setCategoryField(this.categoryField);
	},

	setDataField : function(field){
		this.dataField = field;
		this.swf.setDataField(field);
	},

	setCategoryField : function(field){
		this.categoryField = field;
		this.swf.setCategoryField(field);
	}
});
Ext.reg('piechart', Ext.chart.PieChart);


Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {
	onSwfReady : function(isReset){
		Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset);
		this.labelFn = [];
		if(this.xField){
			this.setXField(this.xField);
		}
		if(this.yField){
			this.setYField(this.yField);
		}
		if(this.xAxis){
			this.setXAxis(this.xAxis);
		}
		if(this.xAxes){
			this.setXAxes(this.xAxes);
		}
		if(this.yAxis){
			this.setYAxis(this.yAxis);
		}
		if(this.yAxes){
			this.setYAxes(this.yAxes);
		}
		if(Ext.isDefined(this.constrainViewport)){
			this.swf.setConstrainViewport(this.constrainViewport);
		}
	},

	setXField : function(value){
		this.xField = value;
		this.swf.setHorizontalField(value);
	},

	setYField : function(value){
		this.yField = value;
		this.swf.setVerticalField(value);
	},

	setXAxis : function(value){
		this.xAxis = this.createAxis('xAxis', value);
		this.swf.setHorizontalAxis(this.xAxis);
	},

	setXAxes : function(value){
		var axis;
		for(var i = 0; i < value.length; i++) {
			axis = this.createAxis('xAxis' + i, value[i]);
			this.swf.setHorizontalAxis(axis);
		}
	},

	setYAxis : function(value){
		this.yAxis = this.createAxis('yAxis', value);
		this.swf.setVerticalAxis(this.yAxis);
	},

	setYAxes : function(value){
		var axis;
		for(var i = 0; i < value.length; i++) {
			axis = this.createAxis('yAxis' + i, value[i]);
			this.swf.setVerticalAxis(axis);
		}
	},

	createAxis : function(axis, value){
		var o = Ext.apply({}, value),
		ref,
		old;

		if(this[axis]){
			old = this[axis].labelFunction;
			this.removeFnProxy(old);
			this.labelFn.remove(old);
		}
		if(o.labelRenderer){
			ref = this.getFunctionRef(o.labelRenderer);
			o.labelFunction = this.createFnProxy(function(v){
				return ref.fn.call(ref.scope, v);
			});
			delete o.labelRenderer;
			this.labelFn.push(o.labelFunction);
		}
		if(axis.indexOf('xAxis') > -1 && o.position == 'left'){
			o.position = 'bottom';
		}
		return o;
	},

	onDestroy : function(){
		Ext.chart.CartesianChart.superclass.onDestroy.call(this);
		Ext.each(this.labelFn, function(fn){
			this.removeFnProxy(fn);
		}, this);
	}
});
Ext.reg('cartesianchart', Ext.chart.CartesianChart);


Ext.chart.LineChart = Ext.extend(Ext.chart.CartesianChart, {
	type: 'line'
});
Ext.reg('linechart', Ext.chart.LineChart);


Ext.chart.ColumnChart = Ext.extend(Ext.chart.CartesianChart, {
	type: 'column'
});
Ext.reg('columnchart', Ext.chart.ColumnChart);


Ext.chart.StackedColumnChart = Ext.extend(Ext.chart.CartesianChart, {
	type: 'stackcolumn'
});
Ext.reg('stackedcolumnchart', Ext.chart.StackedColumnChart);


Ext.chart.BarChart = Ext.extend(Ext.chart.CartesianChart, {
	type: 'bar'
});
Ext.reg('barchart', Ext.chart.BarChart);


Ext.chart.StackedBarChart = Ext.extend(Ext.chart.CartesianChart, {
	type: 'stackbar'
});
Ext.reg('stackedbarchart', Ext.chart.StackedBarChart);




Ext.chart.Axis = function(config){
	Ext.apply(this, config);
};

Ext.chart.Axis.prototype =
{

	type: null,


	orientation: "horizontal",


	reverse: false,


	labelFunction: null,


	hideOverlappingLabels: true,


	labelSpacing: 2
};


Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, {
	type: "numeric",


	minimum: NaN,


	maximum: NaN,


	majorUnit: NaN,


	minorUnit: NaN,


	snapToUnits: true,


	alwaysShowZero: true,


	scale: "linear",


	roundMajorUnit: true,


	calculateByLabelSize: true,


	position: 'left',


	adjustMaximumByMajorUnit: true,


	adjustMinimumByMajorUnit: true

});


Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, {
	type: "time",


	minimum: null,


	maximum: null,


	majorUnit: NaN,


	majorTimeUnit: null,


	minorUnit: NaN,


	minorTimeUnit: null,


	snapToUnits: true,


	stackingEnabled: false,


	calculateByLabelSize: true

});


Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, {
	type: "category",


	categoryNames: null,


	calculateCategoryCount: false

});


Ext.chart.Series = function(config) {
	Ext.apply(this, config);
};

Ext.chart.Series.prototype =
{

	type: null,


	displayName: null
};


Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, {

	xField: null,


	yField: null,


	showInLegend: true,


	axis: 'primary'
});


Ext.chart.ColumnSeries = Ext.extend(Ext.chart.CartesianSeries, {
	type: "column"
});


Ext.chart.LineSeries = Ext.extend(Ext.chart.CartesianSeries, {
	type: "line"
});


Ext.chart.BarSeries = Ext.extend(Ext.chart.CartesianSeries, {
	type: "bar"
});



Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {
	type: "pie",
	dataField: null,
	categoryField: null
});
Ext.menu.Menu = Ext.extend(Ext.Container, {



	minWidth : 120,

	shadow : 'sides',

	subMenuAlign : 'tl-tr?',

	defaultAlign : 'tl-bl?',

	allowOtherMenus : false,

	ignoreParentClicks : false,

	enableScrolling : true,

	maxHeight : null,

	scrollIncrement : 24,

	showSeparator : true,

	defaultOffsets : [0, 0],


	plain : false,


	floating : true,



	zIndex: 15000,


	hidden : true,


	layout : 'menu',
	hideMode : 'offsets',
	scrollerHeight : 8,
	autoLayout : true,
	defaultType : 'menuitem',
	bufferResize : false,

	initComponent : function(){
		if(Ext.isArray(this.initialConfig)){
			Ext.apply(this, {
				items:this.initialConfig
				});
		}
		this.addEvents(

			'click',

			'mouseover',

			'mouseout',

			'itemclick'
			);
		Ext.menu.MenuMgr.register(this);
		if(this.floating){
			Ext.EventManager.onWindowResize(this.hide, this);
		}else{
			if(this.initialConfig.hidden !== false){
				this.hidden = false;
			}
			this.internalDefaults = {
				hideOnClick: false
			};
		}
		Ext.menu.Menu.superclass.initComponent.call(this);
		if(this.autoLayout){
			var fn = this.doLayout.createDelegate(this, []);
			this.on({
				add: fn,
				remove: fn
			});
		}
	},


	getLayoutTarget : function() {
		return this.ul;
	},


	onRender : function(ct, position){
		if(!ct){
			ct = Ext.getBody();
		}

		var dh = {
			id: this.getId(),
			cls: 'x-menu ' + ((this.floating) ? 'x-menu-floating x-layer ' : '') + (this.cls || '') + (this.plain ? ' x-menu-plain' : '') + (this.showSeparator ? '' : ' x-menu-nosep'),
			style: this.style,
			cn: [
			{
				tag: 'a',
				cls: 'x-menu-focus',
				href: '#',
				onclick: 'return false;',
				tabIndex: '-1'
			},

			{
				tag: 'ul',
				cls: 'x-menu-list'
			}
			]
		};
		if(this.floating){
			this.el = new Ext.Layer({
				shadow: this.shadow,
				dh: dh,
				constrain: false,
				parentEl: ct,
				zindex: this.zIndex
			});
		}else{
			this.el = ct.createChild(dh);
		}
		Ext.menu.Menu.superclass.onRender.call(this, ct, position);

		if(!this.keyNav){
			this.keyNav = new Ext.menu.MenuNav(this);
		}

		this.focusEl = this.el.child('a.x-menu-focus');
		this.ul = this.el.child('ul.x-menu-list');
		this.mon(this.ul, {
			scope: this,
			click: this.onClick,
			mouseover: this.onMouseOver,
			mouseout: this.onMouseOut
		});
		if(this.enableScrolling){
			this.mon(this.el, {
				scope: this,
				delegate: '.x-menu-scroller',
				click: this.onScroll,
				mouseover: this.deactivateActive
			});
		}
	},


	findTargetItem : function(e){
		var t = e.getTarget('.x-menu-list-item', this.ul, true);
		if(t && t.menuItemId){
			return this.items.get(t.menuItemId);
		}
	},


	onClick : function(e){
		var t = this.findTargetItem(e);
		if(t){
			if(t.isFormField){
				this.setActiveItem(t);
			}else if(t instanceof Ext.menu.BaseItem){
				if(t.menu && this.ignoreParentClicks){
					t.expandMenu();
					e.preventDefault();
				}else if(t.onClick){
					t.onClick(e);
					this.fireEvent('click', this, t, e);
				}
			}
		}
	},


	setActiveItem : function(item, autoExpand){
		if(item != this.activeItem){
			this.deactivateActive();
			if((this.activeItem = item).isFormField){
				item.focus();
			}else{
				item.activate(autoExpand);
			}
		}else if(autoExpand){
			item.expandMenu();
		}
	},

	deactivateActive : function(){
		var a = this.activeItem;
		if(a){
			if(a.isFormField){

				if(a.collapse){
					a.collapse();
				}
			}else{
				a.deactivate();
			}
			delete this.activeItem;
		}
	},


	tryActivate : function(start, step){
		var items = this.items;
		for(var i = start, len = items.length; i >= 0 && i < len; i+= step){
			var item = items.get(i);
			if(item.isVisible() && !item.disabled && (item.canActivate || item.isFormField)){
				this.setActiveItem(item, false);
				return item;
			}
		}
		return false;
	},


	onMouseOver : function(e){
		var t = this.findTargetItem(e);
		if(t){
			if(t.canActivate && !t.disabled){
				this.setActiveItem(t, true);
			}
		}
		this.over = true;
		this.fireEvent('mouseover', this, e, t);
	},


	onMouseOut : function(e){
		var t = this.findTargetItem(e);
		if(t){
			if(t == this.activeItem && t.shouldDeactivate && t.shouldDeactivate(e)){
				this.activeItem.deactivate();
				delete this.activeItem;
			}
		}
		this.over = false;
		this.fireEvent('mouseout', this, e, t);
	},


	onScroll : function(e, t){
		if(e){
			e.stopEvent();
		}
		var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top');
		ul.scrollTop += this.scrollIncrement * (top ? -1 : 1);
		if(top ? ul.scrollTop <= 0 : ul.scrollTop + this.activeMax >= ul.scrollHeight){
			this.onScrollerOut(null, t);
		}
	},


	onScrollerIn : function(e, t){
		var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top');
		if(top ? ul.scrollTop > 0 : ul.scrollTop + this.activeMax < ul.scrollHeight){
			Ext.fly(t).addClass(['x-menu-item-active', 'x-menu-scroller-active']);
		}
	},


	onScrollerOut : function(e, t){
		Ext.fly(t).removeClass(['x-menu-item-active', 'x-menu-scroller-active']);
	},


	show : function(el, pos, parentMenu){
		if(this.floating){
			this.parentMenu = parentMenu;
			if(!this.el){
				this.render();
				this.doLayout(false, true);
			}
			this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign, this.defaultOffsets), parentMenu);
		}else{
			Ext.menu.Menu.superclass.show.call(this);
		}
	},


	showAt : function(xy, parentMenu){
		if(this.fireEvent('beforeshow', this) !== false){
			this.parentMenu = parentMenu;
			if(!this.el){
				this.render();
			}
			if(this.enableScrolling){

				this.el.setXY(xy);

				xy[1] = this.constrainScroll(xy[1]);
				xy = [this.el.adjustForConstraints(xy)[0], xy[1]];
			}else{

				xy = this.el.adjustForConstraints(xy);
			}
			this.el.setXY(xy);
			this.el.show();
			Ext.menu.Menu.superclass.onShow.call(this);
			if(Ext.isIE){

				this.fireEvent('autosize', this);
				if(!Ext.isIE8){
					this.el.repaint();
				}
			}
			this.hidden = false;
			this.focus();
			this.fireEvent('show', this);
		}
	},

	constrainScroll : function(y){
		var max, full = this.ul.setHeight('auto').getHeight(),
		returnY = y, normalY, parentEl, scrollTop, viewHeight;
		if(this.floating){
			parentEl = Ext.fly(this.el.dom.parentNode);
			scrollTop = parentEl.getScroll().top;
			viewHeight = parentEl.getViewSize().height;


			normalY = y - scrollTop;
			max = this.maxHeight ? this.maxHeight : viewHeight - normalY;
			if(full > viewHeight) {
				max = viewHeight;

				returnY = y - normalY;
			} else if(max < full) {
				returnY = y - (full - max);
				max = full;
			}
		}else{
			max = this.getHeight();
		}

		if (this.maxHeight){
			max = Math.min(this.maxHeight, max);
		}
		if(full > max && max > 0){
			this.activeMax = max - this.scrollerHeight * 2 - this.el.getFrameWidth('tb') - Ext.num(this.el.shadowOffset, 0);
			this.ul.setHeight(this.activeMax);
			this.createScrollers();
			this.el.select('.x-menu-scroller').setDisplayed('');
		}else{
			this.ul.setHeight(full);
			this.el.select('.x-menu-scroller').setDisplayed('none');
		}
		this.ul.dom.scrollTop = 0;
		return returnY;
	},

	createScrollers : function(){
		if(!this.scroller){
			this.scroller = {
				pos: 0,
				top: this.el.insertFirst({
					tag: 'div',
					cls: 'x-menu-scroller x-menu-scroller-top',
					html: '&#160;'
				}),
				bottom: this.el.createChild({
					tag: 'div',
					cls: 'x-menu-scroller x-menu-scroller-bottom',
					html: '&#160;'
				})
			};
			this.scroller.top.hover(this.onScrollerIn, this.onScrollerOut, this);
			this.scroller.topRepeater = new Ext.util.ClickRepeater(this.scroller.top, {
				listeners: {
					click: this.onScroll.createDelegate(this, [null, this.scroller.top], false)
				}
			});
			this.scroller.bottom.hover(this.onScrollerIn, this.onScrollerOut, this);
			this.scroller.bottomRepeater = new Ext.util.ClickRepeater(this.scroller.bottom, {
				listeners: {
					click: this.onScroll.createDelegate(this, [null, this.scroller.bottom], false)
				}
			});
		}
	},

	onLayout : function(){
		if(this.isVisible()){
			if(this.enableScrolling){
				this.constrainScroll(this.el.getTop());
			}
			if(this.floating){
				this.el.sync();
			}
		}
	},

	focus : function(){
		if(!this.hidden){
			this.doFocus.defer(50, this);
		}
	},

	doFocus : function(){
		if(!this.hidden){
			this.focusEl.focus();
		}
	},


	hide : function(deep){
		if (!this.isDestroyed) {
			this.deepHide = deep;
			Ext.menu.Menu.superclass.hide.call(this);
			delete this.deepHide;
		}
	},


	onHide : function(){
		Ext.menu.Menu.superclass.onHide.call(this);
		this.deactivateActive();
		if(this.el && this.floating){
			this.el.hide();
		}
		var pm = this.parentMenu;
		if(this.deepHide === true && pm){
			if(pm.floating){
				pm.hide(true);
			}else{
				pm.deactivateActive();
			}
		}
	},


	lookupComponent : function(c){
		if(Ext.isString(c)){
			c = (c == 'separator' || c == '-') ? new Ext.menu.Separator() : new Ext.menu.TextItem(c);
			this.applyDefaults(c);
		}else{
			if(Ext.isObject(c)){
				c = this.getMenuItem(c);
			}else if(c.tagName || c.el){
				c = new Ext.BoxComponent({
					el: c
				});
			}
		}
		return c;
	},

	applyDefaults : function(c) {
		if (!Ext.isString(c)) {
			c = Ext.menu.Menu.superclass.applyDefaults.call(this, c);
			var d = this.internalDefaults;
			if(d){
				if(c.events){
					Ext.applyIf(c.initialConfig, d);
					Ext.apply(c, d);
				}else{
					Ext.applyIf(c, d);
				}
			}
		}
		return c;
	},


	getMenuItem : function(config) {
		if (!config.isXType) {
			if (!config.xtype && Ext.isBoolean(config.checked)) {
				return new Ext.menu.CheckItem(config);
			}
			return Ext.create(config, this.defaultType);
		}
		return config;
	},


	addSeparator : function() {
		return this.add(new Ext.menu.Separator());
	},


	addElement : function(el) {
		return this.add(new Ext.menu.BaseItem({
			el: el
		}));
	},


	addItem : function(item) {
		return this.add(item);
	},


	addMenuItem : function(config) {
		return this.add(this.getMenuItem(config));
	},


	addText : function(text){
		return this.add(new Ext.menu.TextItem(text));
	},


	onDestroy : function(){
		Ext.EventManager.removeResizeListener(this.hide, this);
		var pm = this.parentMenu;
		if(pm && pm.activeChild == this){
			delete pm.activeChild;
		}
		delete this.parentMenu;
		Ext.menu.Menu.superclass.onDestroy.call(this);
		Ext.menu.MenuMgr.unregister(this);
		if(this.keyNav) {
			this.keyNav.disable();
		}
		var s = this.scroller;
		if(s){
			Ext.destroy(s.topRepeater, s.bottomRepeater, s.top, s.bottom);
		}
		Ext.destroy(
			this.el,
			this.focusEl,
			this.ul
			);
	}
});

Ext.reg('menu', Ext.menu.Menu);


Ext.menu.MenuNav = Ext.extend(Ext.KeyNav, function(){
	function up(e, m){
		if(!m.tryActivate(m.items.indexOf(m.activeItem)-1, -1)){
			m.tryActivate(m.items.length-1, -1);
		}
	}
	function down(e, m){
		if(!m.tryActivate(m.items.indexOf(m.activeItem)+1, 1)){
			m.tryActivate(0, 1);
		}
	}
	return {
		constructor : function(menu){
			Ext.menu.MenuNav.superclass.constructor.call(this, menu.el);
			this.scope = this.menu = menu;
		},

		doRelay : function(e, h){
			var k = e.getKey();

			if (this.menu.activeItem && this.menu.activeItem.isFormField && k != e.TAB) {
				return false;
			}
			if(!this.menu.activeItem && e.isNavKeyPress() && k != e.SPACE && k != e.RETURN){
				this.menu.tryActivate(0, 1);
				return false;
			}
			return h.call(this.scope || this, e, this.menu);
		},

		tab: function(e, m) {
			e.stopEvent();
			if (e.shiftKey) {
				up(e, m);
			} else {
				down(e, m);
			}
		},

		up : up,

		down : down,

		right : function(e, m){
			if(m.activeItem){
				m.activeItem.expandMenu(true);
			}
		},

		left : function(e, m){
			m.hide();
			if(m.parentMenu && m.parentMenu.activeItem){
				m.parentMenu.activeItem.activate();
			}
		},

		enter : function(e, m){
			if(m.activeItem){
				e.stopPropagation();
				m.activeItem.onClick(e);
				m.fireEvent('click', this, m.activeItem);
				return true;
			}
		}
	};
}());

Ext.menu.MenuMgr = function(){
	var menus, active, groups = {}, attached = false, lastShow = new Date();


	function init(){
		menus = {};
		active = new Ext.util.MixedCollection();
		Ext.getDoc().addKeyListener(27, function(){
			if(active.length > 0){
				hideAll();
			}
		});
	}


	function hideAll(){
		if(active && active.length > 0){
			var c = active.clone();
			c.each(function(m){
				m.hide();
			});
			return true;
		}
		return false;
	}


	function onHide(m){
		active.remove(m);
		if(active.length < 1){
			Ext.getDoc().un("mousedown", onMouseDown);
			attached = false;
		}
	}


	function onShow(m){
		var last = active.last();
		lastShow = new Date();
		active.add(m);
		if(!attached){
			Ext.getDoc().on("mousedown", onMouseDown);
			attached = true;
		}
		if(m.parentMenu){
			m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3);
			m.parentMenu.activeChild = m;
		}else if(last && !last.isDestroyed && last.isVisible()){
			m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3);
		}
	}


	function onBeforeHide(m){
		if(m.activeChild){
			m.activeChild.hide();
		}
		if(m.autoHideTimer){
			clearTimeout(m.autoHideTimer);
			delete m.autoHideTimer;
		}
	}


	function onBeforeShow(m){
		var pm = m.parentMenu;
		if(!pm && !m.allowOtherMenus){
			hideAll();
		}else if(pm && pm.activeChild){
			pm.activeChild.hide();
		}
	}


	function onMouseDown(e){
		if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){
			hideAll();
		}
	}

	return {


		hideAll : function(){
			return hideAll();
		},


		register : function(menu){
			if(!menus){
				init();
			}
			menus[menu.id] = menu;
			menu.on({
				beforehide: onBeforeHide,
				hide: onHide,
				beforeshow: onBeforeShow,
				show: onShow
			});
		},


		get : function(menu){
			if(typeof menu == "string"){
				if(!menus){
					return null;
				}
				return menus[menu];
			}else if(menu.events){
				return menu;
			}else if(typeof menu.length == 'number'){
				return new Ext.menu.Menu({
					items:menu
				});
			}else{
				return Ext.create(menu, 'menu');
			}
		},


		unregister : function(menu){
			delete menus[menu.id];
			menu.un("beforehide", onBeforeHide);
			menu.un("hide", onHide);
			menu.un("beforeshow", onBeforeShow);
			menu.un("show", onShow);
		},


		registerCheckable : function(menuItem){
			var g = menuItem.group;
			if(g){
				if(!groups[g]){
					groups[g] = [];
				}
				groups[g].push(menuItem);
			}
		},


		unregisterCheckable : function(menuItem){
			var g = menuItem.group;
			if(g){
				groups[g].remove(menuItem);
			}
		},


		onCheckChange: function(item, state){
			if(item.group && state){
				var group = groups[item.group],
				i = 0,
				len = group.length,
				current;

				for(; i < len; i++){
					current = group[i];
					if(current != item){
						current.setChecked(false);
					}
				}
			}
		},

		getCheckedItem : function(groupId){
			var g = groups[groupId];
			if(g){
				for(var i = 0, l = g.length; i < l; i++){
					if(g[i].checked){
						return g[i];
					}
				}
			}
			return null;
		},

		setCheckedItem : function(groupId, itemId){
			var g = groups[groupId];
			if(g){
				for(var i = 0, l = g.length; i < l; i++){
					if(g[i].id == itemId){
						g[i].setChecked(true);
					}
				}
			}
			return null;
		}
	};
}();

Ext.menu.BaseItem = Ext.extend(Ext.Component, {




	canActivate : false,

	activeClass : "x-menu-item-active",

	hideOnClick : true,

	clickHideDelay : 1,


	ctype : "Ext.menu.BaseItem",


	actionMode : "container",

	initComponent : function(){
		Ext.menu.BaseItem.superclass.initComponent.call(this);
		this.addEvents(

			'click',

			'activate',

			'deactivate'
			);
		if(this.handler){
			this.on("click", this.handler, this.scope);
		}
	},


	onRender : function(container, position){
		Ext.menu.BaseItem.superclass.onRender.apply(this, arguments);
		if(this.ownerCt && this.ownerCt instanceof Ext.menu.Menu){
			this.parentMenu = this.ownerCt;
		}else{
			this.container.addClass('x-menu-list-item');
			this.mon(this.el, {
				scope: this,
				click: this.onClick,
				mouseenter: this.activate,
				mouseleave: this.deactivate
			});
		}
	},


	setHandler : function(handler, scope){
		if(this.handler){
			this.un("click", this.handler, this.scope);
		}
		this.on("click", this.handler = handler, this.scope = scope);
	},


	onClick : function(e){
		if(!this.disabled && this.fireEvent("click", this, e) !== false
			&& (this.parentMenu && this.parentMenu.fireEvent("itemclick", this, e) !== false)){
			this.handleClick(e);
		}else{
			e.stopEvent();
		}
	},


	activate : function(){
		if(this.disabled){
			return false;
		}
		var li = this.container;
		li.addClass(this.activeClass);
		this.region = li.getRegion().adjust(2, 2, -2, -2);
		this.fireEvent("activate", this);
		return true;
	},


	deactivate : function(){
		this.container.removeClass(this.activeClass);
		this.fireEvent("deactivate", this);
	},


	shouldDeactivate : function(e){
		return !this.region || !this.region.contains(e.getPoint());
	},


	handleClick : function(e){
		var pm = this.parentMenu;
		if(this.hideOnClick){
			if(pm.floating){
				pm.hide.defer(this.clickHideDelay, pm, [true]);
			}else{
				pm.deactivateActive();
			}
		}
	},


	expandMenu : Ext.emptyFn,


	hideMenu : Ext.emptyFn
});
Ext.reg('menubaseitem', Ext.menu.BaseItem);
Ext.menu.TextItem = Ext.extend(Ext.menu.BaseItem, {


	hideOnClick : false,

	itemCls : "x-menu-text",

	constructor : function(config) {
		if (typeof config == 'string') {
			config = {
				text: config
			};
		}
		Ext.menu.TextItem.superclass.constructor.call(this, config);
	},


	onRender : function() {
		var s = document.createElement("span");
		s.className = this.itemCls;
		s.innerHTML = this.text;
		this.el = s;
		Ext.menu.TextItem.superclass.onRender.apply(this, arguments);
	}
});
Ext.reg('menutextitem', Ext.menu.TextItem);
Ext.menu.Separator = Ext.extend(Ext.menu.BaseItem, {

	itemCls : "x-menu-sep",

	hideOnClick : false,


	activeClass: '',


	onRender : function(li){
		var s = document.createElement("span");
		s.className = this.itemCls;
		s.innerHTML = "&#160;";
		this.el = s;
		li.addClass("x-menu-sep-li");
		Ext.menu.Separator.superclass.onRender.apply(this, arguments);
	}
});
Ext.reg('menuseparator', Ext.menu.Separator);
Ext.menu.Item = Ext.extend(Ext.menu.BaseItem, {








	itemCls : 'x-menu-item',

	canActivate : true,

	showDelay: 200,


	altText: '',


	hideDelay: 200,


	ctype: 'Ext.menu.Item',

	initComponent : function(){
		Ext.menu.Item.superclass.initComponent.call(this);
		if(this.menu){
			this.menu = Ext.menu.MenuMgr.get(this.menu);
			this.menu.ownerCt = this;
		}
	},


	onRender : function(container, position){
		if (!this.itemTpl) {
			this.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate(
				'<a id="{id}" class="{cls}" hidefocus="true" unselectable="on" href="{href}"',
				'<tpl if="hrefTarget">',
				' target="{hrefTarget}"',
				'</tpl>',
				'>',
				'<img alt="{altText}" src="{icon}" class="x-menu-item-icon {iconCls}"/>',
				'<span class="x-menu-item-text">{text}</span>',
				'</a>'
				);
		}
		var a = this.getTemplateArgs();
		this.el = position ? this.itemTpl.insertBefore(position, a, true) : this.itemTpl.append(container, a, true);
		this.iconEl = this.el.child('img.x-menu-item-icon');
		this.textEl = this.el.child('.x-menu-item-text');
		if(!this.href) {
			this.mon(this.el, 'click', Ext.emptyFn, null, {
				preventDefault: true
			});
		}
		Ext.menu.Item.superclass.onRender.call(this, container, position);
	},

	getTemplateArgs: function() {
		return {
			id: this.id,
			cls: this.itemCls + (this.menu ?  ' x-menu-item-arrow' : '') + (this.cls ?  ' ' + this.cls : ''),
			href: this.href || '#',
			hrefTarget: this.hrefTarget,
			icon: this.icon || Ext.BLANK_IMAGE_URL,
			iconCls: this.iconCls || '',
			text: this.itemText||this.text||'&#160;',
			altText: this.altText || ''
		};
	},


	setText : function(text){
		this.text = text||'&#160;';
		if(this.rendered){
			this.textEl.update(this.text);
			this.parentMenu.layout.doAutoSize();
		}
	},


	setIconClass : function(cls){
		var oldCls = this.iconCls;
		this.iconCls = cls;
		if(this.rendered){
			this.iconEl.replaceClass(oldCls, this.iconCls);
		}
	},


	beforeDestroy: function(){
		if (this.menu){
			delete this.menu.ownerCt;
			this.menu.destroy();
		}
		Ext.menu.Item.superclass.beforeDestroy.call(this);
	},


	handleClick : function(e){
		if(!this.href){
			e.stopEvent();
		}
		Ext.menu.Item.superclass.handleClick.apply(this, arguments);
	},


	activate : function(autoExpand){
		if(Ext.menu.Item.superclass.activate.apply(this, arguments)){
			this.focus();
			if(autoExpand){
				this.expandMenu();
			}
		}
		return true;
	},


	shouldDeactivate : function(e){
		if(Ext.menu.Item.superclass.shouldDeactivate.call(this, e)){
			if(this.menu && this.menu.isVisible()){
				return !this.menu.getEl().getRegion().contains(e.getPoint());
			}
			return true;
		}
		return false;
	},


	deactivate : function(){
		Ext.menu.Item.superclass.deactivate.apply(this, arguments);
		this.hideMenu();
	},


	expandMenu : function(autoActivate){
		if(!this.disabled && this.menu){
			clearTimeout(this.hideTimer);
			delete this.hideTimer;
			if(!this.menu.isVisible() && !this.showTimer){
				this.showTimer = this.deferExpand.defer(this.showDelay, this, [autoActivate]);
			}else if (this.menu.isVisible() && autoActivate){
				this.menu.tryActivate(0, 1);
			}
		}
	},


	deferExpand : function(autoActivate){
		delete this.showTimer;
		this.menu.show(this.container, this.parentMenu.subMenuAlign || 'tl-tr?', this.parentMenu);
		if(autoActivate){
			this.menu.tryActivate(0, 1);
		}
	},


	hideMenu : function(){
		clearTimeout(this.showTimer);
		delete this.showTimer;
		if(!this.hideTimer && this.menu && this.menu.isVisible()){
			this.hideTimer = this.deferHide.defer(this.hideDelay, this);
		}
	},


	deferHide : function(){
		delete this.hideTimer;
		if(this.menu.over){
			this.parentMenu.setActiveItem(this, false);
		}else{
			this.menu.hide();
		}
	}
});
Ext.reg('menuitem', Ext.menu.Item);
Ext.menu.CheckItem = Ext.extend(Ext.menu.Item, {


	itemCls : "x-menu-item x-menu-check-item",

	groupClass : "x-menu-group-item",


	checked: false,


	ctype: "Ext.menu.CheckItem",

	initComponent : function(){
		Ext.menu.CheckItem.superclass.initComponent.call(this);
		this.addEvents(

			"beforecheckchange" ,

			"checkchange"
			);

		if(this.checkHandler){
			this.on('checkchange', this.checkHandler, this.scope);
		}
		Ext.menu.MenuMgr.registerCheckable(this);
	},


	onRender : function(c){
		Ext.menu.CheckItem.superclass.onRender.apply(this, arguments);
		if(this.group){
			this.el.addClass(this.groupClass);
		}
		if(this.checked){
			this.checked = false;
			this.setChecked(true, true);
		}
	},


	destroy : function(){
		Ext.menu.MenuMgr.unregisterCheckable(this);
		Ext.menu.CheckItem.superclass.destroy.apply(this, arguments);
	},


	setChecked : function(state, suppressEvent){
		var suppress = suppressEvent === true;
		if(this.checked != state && (suppress || this.fireEvent("beforecheckchange", this, state) !== false)){
			Ext.menu.MenuMgr.onCheckChange(this, state);
			if(this.container){
				this.container[state ? "addClass" : "removeClass"]("x-menu-item-checked");
			}
			this.checked = state;
			if(!suppress){
				this.fireEvent("checkchange", this, state);
			}
		}
	},


	handleClick : function(e){
		if(!this.disabled && !(this.checked && this.group)){
			this.setChecked(!this.checked);
		}
		Ext.menu.CheckItem.superclass.handleClick.apply(this, arguments);
	}
});
Ext.reg('menucheckitem', Ext.menu.CheckItem);
Ext.menu.DateMenu = Ext.extend(Ext.menu.Menu, {

	enableScrolling : false,



	hideOnClick : true,


	pickerId : null,




	cls : 'x-date-menu',





	initComponent : function(){
		this.on('beforeshow', this.onBeforeShow, this);
		if(this.strict = (Ext.isIE7 && Ext.isStrict)){
			this.on('show', this.onShow, this, {
				single: true,
				delay: 20
			});
		}
		Ext.apply(this, {
			plain: true,
			showSeparator: false,
			items: this.picker = new Ext.DatePicker(Ext.applyIf({
				internalRender: this.strict || !Ext.isIE,
				ctCls: 'x-menu-date-item',
				id: this.pickerId
			}, this.initialConfig))
		});
		this.picker.purgeListeners();
		Ext.menu.DateMenu.superclass.initComponent.call(this);

		this.relayEvents(this.picker, ['select']);
		this.on('show', this.picker.focus, this.picker);
		this.on('select', this.menuHide, this);
		if(this.handler){
			this.on('select', this.handler, this.scope || this);
		}
	},

	menuHide : function() {
		if(this.hideOnClick){
			this.hide(true);
		}
	},

	onBeforeShow : function(){
		if(this.picker){
			this.picker.hideMonthPicker(true);
		}
	},

	onShow : function(){
		var el = this.picker.getEl();
		el.setWidth(el.getWidth());
	}
});
Ext.reg('datemenu', Ext.menu.DateMenu);

Ext.menu.ColorMenu = Ext.extend(Ext.menu.Menu, {

	enableScrolling : false,




	hideOnClick : true,

	cls : 'x-color-menu',


	paletteId : null,










	initComponent : function(){
		Ext.apply(this, {
			plain: true,
			showSeparator: false,
			items: this.palette = new Ext.ColorPalette(Ext.applyIf({
				id: this.paletteId
			}, this.initialConfig))
		});
		this.palette.purgeListeners();
		Ext.menu.ColorMenu.superclass.initComponent.call(this);

		this.relayEvents(this.palette, ['select']);
		this.on('select', this.menuHide, this);
		if(this.handler){
			this.on('select', this.handler, this.scope || this);
		}
	},

	menuHide : function(){
		if(this.hideOnClick){
			this.hide(true);
		}
	}
});
Ext.reg('colormenu', Ext.menu.ColorMenu);

Ext.form.Field = Ext.extend(Ext.BoxComponent,  {








	invalidClass : 'x-form-invalid',

	invalidText : 'The value in this field is invalid',

	focusClass : 'x-form-focus',


	validationEvent : 'keyup',

	validateOnBlur : true,

	validationDelay : 250,

	defaultAutoCreate : {
		tag: 'input',
		type: 'text',
		size: '20',
		autocomplete: 'off'
	},

	fieldClass : 'x-form-field',

	msgTarget : 'qtip',

	msgFx : 'normal',

	readOnly : false,

	disabled : false,

	submitValue: true,


	isFormField : true,


	msgDisplay: '',


	hasFocus : false,


	initComponent : function(){
		Ext.form.Field.superclass.initComponent.call(this);
		this.addEvents(

			'focus',

			'blur',

			'specialkey',

			'change',

			'invalid',

			'valid'
			);
	},


	getName : function(){
		return this.rendered && this.el.dom.name ? this.el.dom.name : this.name || this.id || '';
	},


	onRender : function(ct, position){
		if(!this.el){
			var cfg = this.getAutoCreate();

			if(!cfg.name){
				cfg.name = this.name || this.id;
			}
			if(this.inputType){
				cfg.type = this.inputType;
			}
			this.autoEl = cfg;
		}
		Ext.form.Field.superclass.onRender.call(this, ct, position);
		if(this.submitValue === false){
			this.el.dom.removeAttribute('name');
		}
		var type = this.el.dom.type;
		if(type){
			if(type == 'password'){
				type = 'text';
			}
			this.el.addClass('x-form-'+type);
		}
		if(this.readOnly){
			this.setReadOnly(true);
		}
		if(this.tabIndex !== undefined){
			this.el.dom.setAttribute('tabIndex', this.tabIndex);
		}

		this.el.addClass([this.fieldClass, this.cls]);
	},


	getItemCt : function(){
		return this.itemCt;
	},


	initValue : function(){
		if(this.value !== undefined){
			this.setValue(this.value);
		}else if(!Ext.isEmpty(this.el.dom.value) && this.el.dom.value != this.emptyText){
			this.setValue(this.el.dom.value);
		}

		this.originalValue = this.getValue();
	},


	isDirty : function() {
		if(this.disabled || !this.rendered) {
			return false;
		}
		return String(this.getValue()) !== String(this.originalValue);
	},


	setReadOnly : function(readOnly){
		if(this.rendered){
			this.el.dom.readOnly = readOnly;
		}
		this.readOnly = readOnly;
	},


	afterRender : function(){
		Ext.form.Field.superclass.afterRender.call(this);
		this.initEvents();
		this.initValue();
	},


	fireKey : function(e){
		if(e.isSpecialKey()){
			this.fireEvent('specialkey', this, e);
		}
	},


	reset : function(){
		this.setValue(this.originalValue);
		this.clearInvalid();
	},


	initEvents : function(){
		this.mon(this.el, Ext.EventManager.getKeyEvent(), this.fireKey,  this);
		this.mon(this.el, 'focus', this.onFocus, this);



		this.mon(this.el, 'blur', this.onBlur, this, this.inEditor ? {
			buffer:10
		} : null);
	},


	preFocus: Ext.emptyFn,


	onFocus : function(){
		this.preFocus();
		if(this.focusClass){
			this.el.addClass(this.focusClass);
		}
		if(!this.hasFocus){
			this.hasFocus = true;

			this.startValue = this.getValue();
			this.fireEvent('focus', this);
		}
	},


	beforeBlur : Ext.emptyFn,


	onBlur : function(){
		this.beforeBlur();
		if(this.focusClass){
			this.el.removeClass(this.focusClass);
		}
		this.hasFocus = false;
		if(this.validationEvent !== false && (this.validateOnBlur || this.validationEvent == 'blur')){
			this.validate();
		}
		var v = this.getValue();
		if(String(v) !== String(this.startValue)){
			this.fireEvent('change', this, v, this.startValue);
		}
		this.fireEvent('blur', this);
		this.postBlur();
	},


	postBlur : Ext.emptyFn,


	isValid : function(preventMark){
		if(this.disabled){
			return true;
		}
		var restore = this.preventMark;
		this.preventMark = preventMark === true;
		var v = this.validateValue(this.processValue(this.getRawValue()));
		this.preventMark = restore;
		return v;
	},


	validate : function(){
		if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
			this.clearInvalid();
			return true;
		}
		return false;
	},


	processValue : function(value){
		return value;
	},


	validateValue : function(value) {

		var error = this.getErrors(value)[0];

		if (error == undefined) {
			return true;
		} else {
			this.markInvalid(error);
			return false;
		}
	},


	getErrors: function() {
		return [];
	},


	getActiveError : function(){
		return this.activeError || '';
	},


	markInvalid : function(msg){

		if (this.rendered && !this.preventMark) {
			msg = msg || this.invalidText;

			var mt = this.getMessageHandler();
			if(mt){
				mt.mark(this, msg);
			}else if(this.msgTarget){
				this.el.addClass(this.invalidClass);
				var t = Ext.getDom(this.msgTarget);
				if(t){
					t.innerHTML = msg;
					t.style.display = this.msgDisplay;
				}
			}
		}

		this.setActiveError(msg);
	},


	clearInvalid : function(){

		if (this.rendered && !this.preventMark) {
			this.el.removeClass(this.invalidClass);
			var mt = this.getMessageHandler();
			if(mt){
				mt.clear(this);
			}else if(this.msgTarget){
				this.el.removeClass(this.invalidClass);
				var t = Ext.getDom(this.msgTarget);
				if(t){
					t.innerHTML = '';
					t.style.display = 'none';
				}
			}
		}

		this.unsetActiveError();
	},


	setActiveError: function(msg, suppressEvent) {
		this.activeError = msg;
		if (suppressEvent !== true) this.fireEvent('invalid', this, msg);
	},


	unsetActiveError: function(suppressEvent) {
		delete this.activeError;
		if (suppressEvent !== true) this.fireEvent('valid', this);
	},


	getMessageHandler : function(){
		return Ext.form.MessageTargets[this.msgTarget];
	},


	getErrorCt : function(){
		return this.el.findParent('.x-form-element', 5, true) ||
		this.el.findParent('.x-form-field-wrap', 5, true);
	},


	alignErrorEl : function(){
		this.errorEl.setWidth(this.getErrorCt().getWidth(true) - 20);
	},


	alignErrorIcon : function(){
		this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
	},


	getRawValue : function(){
		var v = this.rendered ? this.el.getValue() : Ext.value(this.value, '');
		if(v === this.emptyText){
			v = '';
		}
		return v;
	},


	getValue : function(){
		if(!this.rendered) {
			return this.value;
		}
		var v = this.el.getValue();
		if(v === this.emptyText || v === undefined){
			v = '';
		}
		return v;
	},


	setRawValue : function(v){
		return this.rendered ? (this.el.dom.value = (Ext.isEmpty(v) ? '' : v)) : '';
	},


	setValue : function(v){
		this.value = v;
		if(this.rendered){
			this.el.dom.value = (Ext.isEmpty(v) ? '' : v);
			this.validate();
		}
		return this;
	},


	append : function(v){
		this.setValue([this.getValue(), v].join(''));
	}





});


Ext.form.MessageTargets = {
	'qtip' : {
		mark: function(field, msg){
			field.el.addClass(field.invalidClass);
			field.el.dom.qtip = msg;
			field.el.dom.qclass = 'x-form-invalid-tip';
			if(Ext.QuickTips){
				Ext.QuickTips.enable();
			}
		},
		clear: function(field){
			field.el.removeClass(field.invalidClass);
			field.el.dom.qtip = '';
		}
	},
	'title' : {
		mark: function(field, msg){
			field.el.addClass(field.invalidClass);
			field.el.dom.title = msg;
		},
		clear: function(field){
			field.el.dom.title = '';
		}
	},
	'under' : {
		mark: function(field, msg){
			field.el.addClass(field.invalidClass);
			if(!field.errorEl){
				var elp = field.getErrorCt();
				if(!elp){
					field.el.dom.title = msg;
					return;
				}
				field.errorEl = elp.createChild({
					cls:'x-form-invalid-msg'
				});
				field.on('resize', field.alignErrorEl, field);
				field.on('destroy', function(){
					Ext.destroy(this.errorEl);
				}, field);
			}
			field.alignErrorEl();
			field.errorEl.update(msg);
			Ext.form.Field.msgFx[field.msgFx].show(field.errorEl, field);
		},
		clear: function(field){
			field.el.removeClass(field.invalidClass);
			if(field.errorEl){
				Ext.form.Field.msgFx[field.msgFx].hide(field.errorEl, field);
			}else{
				field.el.dom.title = '';
			}
		}
	},
	'side' : {
		mark: function(field, msg){
			field.el.addClass(field.invalidClass);
			if(!field.errorIcon){
				var elp = field.getErrorCt();

				if(!elp){
					field.el.dom.title = msg;
					return;
				}
				field.errorIcon = elp.createChild({
					cls:'x-form-invalid-icon'
				});
				if (field.ownerCt) {
					field.ownerCt.on('afterlayout', field.alignErrorIcon, field);
					field.ownerCt.on('expand', field.alignErrorIcon, field);
				}
				field.on('resize', field.alignErrorIcon, field);
				field.on('destroy', function(){
					Ext.destroy(this.errorIcon);
				}, field);
			}
			field.alignErrorIcon();
			field.errorIcon.dom.qtip = msg;
			field.errorIcon.dom.qclass = 'x-form-invalid-tip';
			field.errorIcon.show();
		},
		clear: function(field){
			field.el.removeClass(field.invalidClass);
			if(field.errorIcon){
				field.errorIcon.dom.qtip = '';
				field.errorIcon.hide();
			}else{
				field.el.dom.title = '';
			}
		}
	}
};


Ext.form.Field.msgFx = {
	normal : {
		show: function(msgEl, f){
			msgEl.setDisplayed('block');
		},

		hide : function(msgEl, f){
			msgEl.setDisplayed(false).update('');
		}
	},

	slide : {
		show: function(msgEl, f){
			msgEl.slideIn('t', {
				stopFx:true
			});
		},

		hide : function(msgEl, f){
			msgEl.slideOut('t', {
				stopFx:true,
				useDisplay:true
			});
		}
	},

	slideRight : {
		show: function(msgEl, f){
			msgEl.fixDisplay();
			msgEl.alignTo(f.el, 'tl-tr');
			msgEl.slideIn('l', {
				stopFx:true
			});
		},

		hide : function(msgEl, f){
			msgEl.slideOut('l', {
				stopFx:true,
				useDisplay:true
			});
		}
	}
};
Ext.reg('field', Ext.form.Field);

Ext.form.TextField = Ext.extend(Ext.form.Field,  {



	grow : false,

	growMin : 30,

	growMax : 800,

	vtype : null,

	maskRe : null,

	disableKeyFilter : false,

	allowBlank : true,

	minLength : 0,

	maxLength : Number.MAX_VALUE,

	minLengthText : 'The minimum length for this field is {0}',

	maxLengthText : 'The maximum length for this field is {0}',

	selectOnFocus : false,

	blankText : 'This field is required',

	validator : null,

	regex : null,

	regexText : '',

	emptyText : null,

	emptyClass : 'x-form-empty-field',



	initComponent : function(){
		Ext.form.TextField.superclass.initComponent.call(this);
		this.addEvents(

			'autosize',


			'keydown',

			'keyup',

			'keypress'
			);
	},


	initEvents : function(){
		Ext.form.TextField.superclass.initEvents.call(this);
		if(this.validationEvent == 'keyup'){
			this.validationTask = new Ext.util.DelayedTask(this.validate, this);
			this.mon(this.el, 'keyup', this.filterValidation, this);
		}
		else if(this.validationEvent !== false && this.validationEvent != 'blur'){
			this.mon(this.el, this.validationEvent, this.validate, this, {
				buffer: this.validationDelay
				});
		}
		if(this.selectOnFocus || this.emptyText){
			this.mon(this.el, 'mousedown', this.onMouseDown, this);

			if(this.emptyText){
				this.applyEmptyText();
			}
		}
		if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Ext.form.VTypes[this.vtype+'Mask']))){
			this.mon(this.el, 'keypress', this.filterKeys, this);
		}
		if(this.grow){
			this.mon(this.el, 'keyup', this.onKeyUpBuffered, this, {
				buffer: 50
			});
			this.mon(this.el, 'click', this.autoSize, this);
		}
		if(this.enableKeyEvents){
			this.mon(this.el, {
				scope: this,
				keyup: this.onKeyUp,
				keydown: this.onKeyDown,
				keypress: this.onKeyPress
			});
		}
	},

	onMouseDown: function(e){
		if(!this.hasFocus){
			this.mon(this.el, 'mouseup', Ext.emptyFn, this, {
				single: true,
				preventDefault: true
			});
		}
	},

	processValue : function(value){
		if(this.stripCharsRe){
			var newValue = value.replace(this.stripCharsRe, '');
			if(newValue !== value){
				this.setRawValue(newValue);
				return newValue;
			}
		}
		return value;
	},

	filterValidation : function(e){
		if(!e.isNavKeyPress()){
			this.validationTask.delay(this.validationDelay);
		}
	},


	onDisable: function(){
		Ext.form.TextField.superclass.onDisable.call(this);
		if(Ext.isIE){
			this.el.dom.unselectable = 'on';
		}
	},


	onEnable: function(){
		Ext.form.TextField.superclass.onEnable.call(this);
		if(Ext.isIE){
			this.el.dom.unselectable = '';
		}
	},


	onKeyUpBuffered : function(e){
		if(this.doAutoSize(e)){
			this.autoSize();
		}
	},


	doAutoSize : function(e){
		return !e.isNavKeyPress();
	},


	onKeyUp : function(e){
		this.fireEvent('keyup', this, e);
	},


	onKeyDown : function(e){
		this.fireEvent('keydown', this, e);
	},


	onKeyPress : function(e){
		this.fireEvent('keypress', this, e);
	},


	reset : function(){
		Ext.form.TextField.superclass.reset.call(this);
		this.applyEmptyText();
	},

	applyEmptyText : function(){
		if(this.rendered && this.emptyText && this.getRawValue().length < 1 && !this.hasFocus){
			this.setRawValue(this.emptyText);
			this.el.addClass(this.emptyClass);
		}
	},


	preFocus : function(){
		var el = this.el,
		isEmpty;
		if(this.emptyText){
			if(el.dom.value == this.emptyText){
				this.setRawValue('');
				isEmpty = true;
			}
			el.removeClass(this.emptyClass);
		}
		if(this.selectOnFocus || isEmpty){
			el.dom.select();
		}
	},


	postBlur : function(){
		this.applyEmptyText();
	},


	filterKeys : function(e){
		if(e.ctrlKey){
			return;
		}
		var k = e.getKey();
		if(Ext.isGecko && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
			return;
		}
		var cc = String.fromCharCode(e.getCharCode());
		if(!Ext.isGecko && e.isSpecialKey() && !cc){
			return;
		}
		if(!this.maskRe.test(cc)){
			e.stopEvent();
		}
	},

	setValue : function(v){
		if(this.emptyText && this.el && !Ext.isEmpty(v)){
			this.el.removeClass(this.emptyClass);
		}
		Ext.form.TextField.superclass.setValue.apply(this, arguments);
		this.applyEmptyText();
		this.autoSize();
		return this;
	},


	getErrors: function(value) {
		var errors = Ext.form.TextField.superclass.getErrors.apply(this, arguments);

		value = Ext.isDefined(value) ? value : this.processValue(this.getRawValue());

		if (Ext.isFunction(this.validator)) {
			var msg = this.validator(value);
			if (msg !== true) {
				errors.push(msg);
			}
		}

		if (value.length < 1 || value === this.emptyText) {
			if (this.allowBlank) {

				return errors;
			} else {
				errors.push(this.blankText);
			}
		}

		if (!this.allowBlank && (value.length < 1 || value === this.emptyText)) {
			errors.push(this.blankText);
		}

		if (value.length < this.minLength) {
			errors.push(String.format(this.minLengthText, this.minLength));
		}

		if (value.length > this.maxLength) {
			errors.push(String.format(this.maxLengthText, this.maxLength));
		}

		if (this.vtype) {
			var vt = Ext.form.VTypes;
			if(!vt[this.vtype](value, this)){
				errors.push(this.vtypeText || vt[this.vtype +'Text']);
			}
		}

		if (this.regex && !this.regex.test(value)) {
			errors.push(this.regexText);
		}

		return errors;
	},


	selectText : function(start, end){
		var v = this.getRawValue();
		var doFocus = false;
		if(v.length > 0){
			start = start === undefined ? 0 : start;
			end = end === undefined ? v.length : end;
			var d = this.el.dom;
			if(d.setSelectionRange){
				d.setSelectionRange(start, end);
			}else if(d.createTextRange){
				var range = d.createTextRange();
				range.moveStart('character', start);
				range.moveEnd('character', end-v.length);
				range.select();
			}
			doFocus = Ext.isGecko || Ext.isOpera;
		}else{
			doFocus = true;
		}
		if(doFocus){
			this.focus();
		}
	},


	autoSize : function(){
		if(!this.grow || !this.rendered){
			return;
		}
		if(!this.metrics){
			this.metrics = Ext.util.TextMetrics.createInstance(this.el);
		}
		var el = this.el;
		var v = el.dom.value;
		var d = document.createElement('div');
		d.appendChild(document.createTextNode(v));
		v = d.innerHTML;
		Ext.removeNode(d);
		d = null;
		v += '&#160;';
		var w = Math.min(this.growMax, Math.max(this.metrics.getWidth(v) +  10, this.growMin));
		this.el.setWidth(w);
		this.fireEvent('autosize', this, w);
	},

	onDestroy: function(){
		if(this.validationTask){
			this.validationTask.cancel();
			this.validationTask = null;
		}
		Ext.form.TextField.superclass.onDestroy.call(this);
	}
});
Ext.reg('textfield', Ext.form.TextField);

Ext.form.TriggerField = Ext.extend(Ext.form.TextField,  {



	defaultAutoCreate : {
		tag: "input",
		type: "text",
		size: "16",
		autocomplete: "off"
	},

	hideTrigger:false,

	editable: true,

	readOnly: false,

	wrapFocusClass: 'x-trigger-wrap-focus',

	autoSize: Ext.emptyFn,

	monitorTab : true,

	deferHeight : true,

	mimicing : false,

	actionMode: 'wrap',

	defaultTriggerWidth: 17,


	onResize : function(w, h){
		Ext.form.TriggerField.superclass.onResize.call(this, w, h);
		var tw = this.getTriggerWidth();
		if(Ext.isNumber(w)){
			this.el.setWidth(w - tw);
		}
		this.wrap.setWidth(this.el.getWidth() + tw);
	},

	getTriggerWidth: function(){
		var tw = this.trigger.getWidth();
		if(!this.hideTrigger && !this.readOnly && tw === 0){
			tw = this.defaultTriggerWidth;
		}
		return tw;
	},


	alignErrorIcon : function(){
		if(this.wrap){
			this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
		}
	},


	onRender : function(ct, position){
		this.doc = Ext.isIE ? Ext.getBody() : Ext.getDoc();
		Ext.form.TriggerField.superclass.onRender.call(this, ct, position);

		this.wrap = this.el.wrap({
			cls: 'x-form-field-wrap x-form-field-trigger-wrap'
		});
		this.trigger = this.wrap.createChild(this.triggerConfig ||
		{
			tag: "img",
			src: Ext.BLANK_IMAGE_URL,
			alt: "",
			cls: "x-form-trigger " + this.triggerClass
			});
		this.initTrigger();
		if(!this.width){
			this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
		}
		this.resizeEl = this.positionEl = this.wrap;
	},

	getWidth: function() {
		return(this.el.getWidth() + this.trigger.getWidth());
	},

	updateEditState: function(){
		if(this.rendered){
			if (this.readOnly) {
				this.el.dom.readOnly = true;
				this.el.addClass('x-trigger-noedit');
				this.mun(this.el, 'click', this.onTriggerClick, this);
				this.trigger.setDisplayed(false);
			} else {
				if (!this.editable) {
					this.el.dom.readOnly = true;
					this.el.addClass('x-trigger-noedit');
					this.mon(this.el, 'click', this.onTriggerClick, this);
				} else {
					this.el.dom.readOnly = false;
					this.el.removeClass('x-trigger-noedit');
					this.mun(this.el, 'click', this.onTriggerClick, this);
				}
				this.trigger.setDisplayed(!this.hideTrigger);
			}
			this.onResize(this.width || this.wrap.getWidth());
		}
	},


	setHideTrigger: function(hideTrigger){
		if(hideTrigger != this.hideTrigger){
			this.hideTrigger = hideTrigger;
			this.updateEditState();
		}
	},


	setEditable: function(editable){
		if(editable != this.editable){
			this.editable = editable;
			this.updateEditState();
		}
	},


	setReadOnly: function(readOnly){
		if(readOnly != this.readOnly){
			this.readOnly = readOnly;
			this.updateEditState();
		}
	},

	afterRender : function(){
		Ext.form.TriggerField.superclass.afterRender.call(this);
		this.updateEditState();
	},


	initTrigger : function(){
		this.mon(this.trigger, 'click', this.onTriggerClick, this, {
			preventDefault:true
		});
		this.trigger.addClassOnOver('x-form-trigger-over');
		this.trigger.addClassOnClick('x-form-trigger-click');
	},


	onDestroy : function(){
		Ext.destroy(this.trigger, this.wrap);
		if (this.mimicing){
			this.doc.un('mousedown', this.mimicBlur, this);
		}
		delete this.doc;
		Ext.form.TriggerField.superclass.onDestroy.call(this);
	},


	onFocus : function(){
		Ext.form.TriggerField.superclass.onFocus.call(this);
		if(!this.mimicing){
			this.wrap.addClass(this.wrapFocusClass);
			this.mimicing = true;
			this.doc.on('mousedown', this.mimicBlur, this, {
				delay: 10
			});
			if(this.monitorTab){
				this.on('specialkey', this.checkTab, this);
			}
		}
	},


	checkTab : function(me, e){
		if(e.getKey() == e.TAB){
			this.triggerBlur();
		}
	},


	onBlur : Ext.emptyFn,


	mimicBlur : function(e){
		if(!this.isDestroyed && !this.wrap.contains(e.target) && this.validateBlur(e)){
			this.triggerBlur();
		}
	},


	triggerBlur : function(){
		this.mimicing = false;
		this.doc.un('mousedown', this.mimicBlur, this);
		if(this.monitorTab && this.el){
			this.un('specialkey', this.checkTab, this);
		}
		Ext.form.TriggerField.superclass.onBlur.call(this);
		if(this.wrap){
			this.wrap.removeClass(this.wrapFocusClass);
		}
	},

	beforeBlur : Ext.emptyFn,



	validateBlur : function(e){
		return true;
	},


	onTriggerClick : Ext.emptyFn




});


Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, {




	initComponent : function(){
		Ext.form.TwinTriggerField.superclass.initComponent.call(this);

		this.triggerConfig = {
			tag:'span',
			cls:'x-form-twin-triggers',
			cn:[

			{
				tag: "img",
				src: Ext.BLANK_IMAGE_URL,
				alt: "",
				cls: "x-form-trigger " + this.trigger1Class
				},

				{
				tag: "img",
				src: Ext.BLANK_IMAGE_URL,
				alt: "",
				cls: "x-form-trigger " + this.trigger2Class
				}
			]
			};
	},

	getTrigger : function(index){
		return this.triggers[index];
	},

	afterRender: function(){
		Ext.form.TwinTriggerField.superclass.afterRender.call(this);
		var triggers = this.triggers,
		i = 0,
		len = triggers.length;

		for(; i < len; ++i){
			if(this['hideTrigger' + (i + 1)]){
				triggers[i].hide();
			}

		}
	},

	initTrigger : function(){
		var ts = this.trigger.select('.x-form-trigger', true),
		triggerField = this;

		ts.each(function(t, all, index){
			var triggerIndex = 'Trigger'+(index+1);
			t.hide = function(){
				var w = triggerField.wrap.getWidth();
				this.dom.style.display = 'none';
				triggerField.el.setWidth(w-triggerField.trigger.getWidth());
				triggerField['hidden' + triggerIndex] = true;
			};
			t.show = function(){
				var w = triggerField.wrap.getWidth();
				this.dom.style.display = '';
				triggerField.el.setWidth(w-triggerField.trigger.getWidth());
				triggerField['hidden' + triggerIndex] = false;
			};
			this.mon(t, 'click', this['on'+triggerIndex+'Click'], this, {
				preventDefault:true
			});
			t.addClassOnOver('x-form-trigger-over');
			t.addClassOnClick('x-form-trigger-click');
		}, this);
		this.triggers = ts.elements;
	},

	getTriggerWidth: function(){
		var tw = 0;
		Ext.each(this.triggers, function(t, index){
			var triggerIndex = 'Trigger' + (index + 1),
			w = t.getWidth();
			if(w === 0 && !this['hidden' + triggerIndex]){
				tw += this.defaultTriggerWidth;
			}else{
				tw += w;
			}
		}, this);
		return tw;
	},


	onDestroy : function() {
		Ext.destroy(this.triggers);
		Ext.form.TwinTriggerField.superclass.onDestroy.call(this);
	},


	onTrigger1Click : Ext.emptyFn,

	onTrigger2Click : Ext.emptyFn
});
Ext.reg('trigger', Ext.form.TriggerField);

Ext.form.TextArea = Ext.extend(Ext.form.TextField,  {

	growMin : 60,

	growMax: 1000,
	growAppend : '&#160;\n&#160;',

	enterIsSpecial : false,


	preventScrollbars: false,



	onRender : function(ct, position){
		if(!this.el){
			this.defaultAutoCreate = {
				tag: "textarea",
				style:"width:100px;height:60px;",
				autocomplete: "off"
			};
		}
		Ext.form.TextArea.superclass.onRender.call(this, ct, position);
		if(this.grow){
			this.textSizeEl = Ext.DomHelper.append(document.body, {
				tag: "pre",
				cls: "x-form-grow-sizer"
			});
			if(this.preventScrollbars){
				this.el.setStyle("overflow", "hidden");
			}
			this.el.setHeight(this.growMin);
		}
	},

	onDestroy : function(){
		Ext.removeNode(this.textSizeEl);
		Ext.form.TextArea.superclass.onDestroy.call(this);
	},

	fireKey : function(e){
		if(e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() != e.ENTER || e.hasModifier()))){
			this.fireEvent("specialkey", this, e);
		}
	},


	doAutoSize : function(e){
		return !e.isNavKeyPress() || e.getKey() == e.ENTER;
	},


	filterValidation: function(e) {
		if(!e.isNavKeyPress() || (!this.enterIsSpecial && e.keyCode == e.ENTER)){
			this.validationTask.delay(this.validationDelay);
		}
	},


	autoSize: function(){
		if(!this.grow || !this.textSizeEl){
			return;
		}
		var el = this.el,
		v = Ext.util.Format.htmlEncode(el.dom.value),
		ts = this.textSizeEl,
		h;

		Ext.fly(ts).setWidth(this.el.getWidth());
		if(v.length < 1){
			v = "&#160;&#160;";
		}else{
			v += this.growAppend;
			if(Ext.isIE){
				v = v.replace(/\n/g, '&#160;<br />');
			}
		}
		ts.innerHTML = v;
		h = Math.min(this.growMax, Math.max(ts.offsetHeight, this.growMin));
		if(h != this.lastHeight){
			this.lastHeight = h;
			this.el.setHeight(h);
			this.fireEvent("autosize", this, h);
		}
	}
});
Ext.reg('textarea', Ext.form.TextArea);
Ext.form.NumberField = Ext.extend(Ext.form.TextField,  {



	fieldClass: "x-form-field x-form-num-field",


	allowDecimals : true,


	decimalSeparator : ".",


	decimalPrecision : 2,


	allowNegative : true,


	minValue : Number.NEGATIVE_INFINITY,


	maxValue : Number.MAX_VALUE,


	minText : "The minimum value for this field is {0}",


	maxText : "The maximum value for this field is {0}",


	nanText : "{0} is not a valid number",


	baseChars : "0123456789",


	autoStripChars: false,


	initEvents : function() {
		var allowed = this.baseChars + '';
		if (this.allowDecimals) {
			allowed += this.decimalSeparator;
		}
		if (this.allowNegative) {
			allowed += '-';
		}
		allowed = Ext.escapeRe(allowed);
		this.maskRe = new RegExp('[' + allowed + ']');
		if (this.autoStripChars) {
			this.stripCharsRe = new RegExp('[^' + allowed + ']', 'gi');
		}

		Ext.form.NumberField.superclass.initEvents.call(this);
	},


	getErrors: function(value) {
		var errors = Ext.form.NumberField.superclass.getErrors.apply(this, arguments);

		value = Ext.isDefined(value) ? value : this.processValue(this.getRawValue());

		if (value.length < 1) {
			return errors;
		}

		value = String(value).replace(this.decimalSeparator, ".");

		if(isNaN(value)){
			errors.push(String.format(this.nanText, value));
		}

		var num = this.parseValue(value);

		if (num < this.minValue) {
			errors.push(String.format(this.minText, this.minValue));
		}

		if (num > this.maxValue) {
			errors.push(String.format(this.maxText, this.maxValue));
		}

		return errors;
	},

	getValue : function() {
		return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)));
	},

	setValue : function(v) {
		v = this.fixPrecision(v);
		v = Ext.isNumber(v) ? v : parseFloat(String(v).replace(this.decimalSeparator, "."));
		v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
		return Ext.form.NumberField.superclass.setValue.call(this, v);
	},


	setMinValue : function(value) {
		this.minValue = Ext.num(value, Number.NEGATIVE_INFINITY);
	},


	setMaxValue : function(value) {
		this.maxValue = Ext.num(value, Number.MAX_VALUE);
	},


	parseValue : function(value) {
		value = parseFloat(String(value).replace(this.decimalSeparator, "."));
		return isNaN(value) ? '' : value;
	},


	fixPrecision : function(value) {
		var nan = isNaN(value);

		if (!this.allowDecimals || this.decimalPrecision == -1 || nan || !value) {
			return nan ? '' : value;
		}

		return parseFloat(parseFloat(value).toFixed(this.decimalPrecision));
	},

	beforeBlur : function() {
		var v = this.parseValue(this.getRawValue());

		if (!Ext.isEmpty(v)) {
			this.setValue(v);
		}
	}
});

Ext.reg('numberfield', Ext.form.NumberField);

Ext.form.DateField = Ext.extend(Ext.form.TriggerField,  {

	format : "m/d/Y",

	altFormats : "m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d|n-j|n/j",

	disabledDaysText : "Disabled",

	disabledDatesText : "Disabled",

	minText : "The date in this field must be equal to or after {0}",

	maxText : "The date in this field must be equal to or before {0}",

	invalidText : "{0} is not a valid date - it must be in the format {1}",

	triggerClass : 'x-form-date-trigger',

	showToday : true,


	startDay : 0,








	defaultAutoCreate : {
		tag: "input",
		type: "text",
		size: "10",
		autocomplete: "off"
	},



	initTime: '12',

	initTimeFormat: 'H',


	safeParse : function(value, format) {
		if (/[gGhH]/.test(format.replace(/(\\.)/g, ''))) {

			return Date.parseDate(value, format);
		} else {

			var parsedDate = Date.parseDate(value + ' ' + this.initTime, format + ' ' + this.initTimeFormat);

			if (parsedDate) {
				return parsedDate.clearTime();
			}
		}
	},

	initComponent : function(){
		Ext.form.DateField.superclass.initComponent.call(this);

		this.addEvents(

			'select'
			);

		if(Ext.isString(this.minValue)){
			this.minValue = this.parseDate(this.minValue);
		}
		if(Ext.isString(this.maxValue)){
			this.maxValue = this.parseDate(this.maxValue);
		}
		this.disabledDatesRE = null;
		this.initDisabledDays();
	},

	initEvents: function() {
		Ext.form.DateField.superclass.initEvents.call(this);
		this.keyNav = new Ext.KeyNav(this.el, {
			"down": function(e) {
				this.onTriggerClick();
			},
			scope: this,
			forceKeyDown: true
		});
	},



	initDisabledDays : function(){
		if(this.disabledDates){
			var dd = this.disabledDates,
			len = dd.length - 1,
			re = "(?:";

			Ext.each(dd, function(d, i){
				re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i];
				if(i != len){
					re += '|';
				}
			}, this);
			this.disabledDatesRE = new RegExp(re + ')');
		}
	},


	setDisabledDates : function(dd){
		this.disabledDates = dd;
		this.initDisabledDays();
		if(this.menu){
			this.menu.picker.setDisabledDates(this.disabledDatesRE);
		}
	},


	setDisabledDays : function(dd){
		this.disabledDays = dd;
		if(this.menu){
			this.menu.picker.setDisabledDays(dd);
		}
	},


	setMinValue : function(dt){
		this.minValue = (Ext.isString(dt) ? this.parseDate(dt) : dt);
		if(this.menu){
			this.menu.picker.setMinDate(this.minValue);
		}
	},


	setMaxValue : function(dt){
		this.maxValue = (Ext.isString(dt) ? this.parseDate(dt) : dt);
		if(this.menu){
			this.menu.picker.setMaxDate(this.maxValue);
		}
	},


	getErrors: function(value) {
		var errors = Ext.form.DateField.superclass.getErrors.apply(this, arguments);

		value = this.formatDate(value || this.processValue(this.getRawValue()));

		if (value.length < 1) {
			return errors;
		}

		var svalue = value;
		value = this.parseDate(value);
		if (!value) {
			errors.push(String.format(this.invalidText, svalue, this.format));
			return errors;
		}

		var time = value.getTime();
		if (this.minValue && time < this.minValue.clearTime().getTime()) {
			errors.push(String.format(this.minText, this.formatDate(this.minValue)));
		}

		if (this.maxValue && time > this.maxValue.clearTime().getTime()) {
			errors.push(String.format(this.maxText, this.formatDate(this.maxValue)));
		}

		if (this.disabledDays) {
			var day = value.getDay();

			for(var i = 0; i < this.disabledDays.length; i++) {
				if (day === this.disabledDays[i]) {
					errors.push(this.disabledDaysText);
					break;
				}
			}
		}

		var fvalue = this.formatDate(value);
		if (this.disabledDatesRE && this.disabledDatesRE.test(fvalue)) {
			errors.push(String.format(this.disabledDatesText, fvalue));
		}

		return errors;
	},



	validateBlur : function(){
		return !this.menu || !this.menu.isVisible();
	},


	getValue : function(){
		return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || "";
	},


	setValue : function(date){
		return Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this.parseDate(date)));
	},


	parseDate : function(value) {
		if(!value || Ext.isDate(value)){
			return value;
		}

		var v = this.safeParse(value, this.format),
		af = this.altFormats,
		afa = this.altFormatsArray;

		if (!v && af) {
			afa = afa || af.split("|");

			for (var i = 0, len = afa.length; i < len && !v; i++) {
				v = this.safeParse(value, afa[i]);
			}
		}
		return v;
	},


	onDestroy : function(){
		Ext.destroy(this.menu, this.keyNav);
		Ext.form.DateField.superclass.onDestroy.call(this);
	},


	formatDate : function(date){
		return Ext.isDate(date) ? date.dateFormat(this.format) : date;
	},




	onTriggerClick : function(){
		if(this.disabled){
			return;
		}
		if(this.menu == null){
			this.menu = new Ext.menu.DateMenu({
				hideOnClick: false,
				focusOnSelect: false
			});
		}
		this.onFocus();
		Ext.apply(this.menu.picker,  {
			minDate : this.minValue,
			maxDate : this.maxValue,
			disabledDatesRE : this.disabledDatesRE,
			disabledDatesText : this.disabledDatesText,
			disabledDays : this.disabledDays,
			disabledDaysText : this.disabledDaysText,
			format : this.format,
			showToday : this.showToday,
			startDay: this.startDay,
			minText : String.format(this.minText, this.formatDate(this.minValue)),
			maxText : String.format(this.maxText, this.formatDate(this.maxValue))
		});
		this.menu.picker.setValue(this.getValue() || new Date());
		this.menu.show(this.el, "tl-bl?");
		this.menuEvents('on');
	},


	menuEvents: function(method){
		this.menu[method]('select', this.onSelect, this);
		this.menu[method]('hide', this.onMenuHide, this);
		this.menu[method]('show', this.onFocus, this);
	},

	onSelect: function(m, d){
		this.setValue(d);
		this.fireEvent('select', this, d);
		this.menu.hide();
	},

	onMenuHide: function(){
		this.focus(false, 60);
		this.menuEvents('un');
	},


	beforeBlur : function(){
		var v = this.parseDate(this.getRawValue());
		if(v){
			this.setValue(v);
		}
	}





});
Ext.reg('datefield', Ext.form.DateField);

Ext.form.DisplayField = Ext.extend(Ext.form.Field,  {
	validationEvent : false,
	validateOnBlur : false,
	defaultAutoCreate : {
		tag: "div"
	},

	fieldClass : "x-form-display-field",

	htmlEncode: false,


	initEvents : Ext.emptyFn,

	isValid : function(){
		return true;
	},

	validate : function(){
		return true;
	},

	getRawValue : function(){
		var v = this.rendered ? this.el.dom.innerHTML : Ext.value(this.value, '');
		if(v === this.emptyText){
			v = '';
		}
		if(this.htmlEncode){
			v = Ext.util.Format.htmlDecode(v);
		}
		return v;
	},

	getValue : function(){
		return this.getRawValue();
	},

	getName: function() {
		return this.name;
	},

	setRawValue : function(v){
		if(this.htmlEncode){
			v = Ext.util.Format.htmlEncode(v);
		}
		return this.rendered ? (this.el.dom.innerHTML = (Ext.isEmpty(v) ? '' : v)) : (this.value = v);
	},

	setValue : function(v){
		this.setRawValue(v);
		return this;
	}






});

Ext.reg('displayfield', Ext.form.DisplayField);

Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {







	defaultAutoCreate : {
		tag: "input",
		type: "text",
		size: "24",
		autocomplete: "off"
	},







	listClass : '',

	selectedClass : 'x-combo-selected',

	listEmptyText: '',

	triggerClass : 'x-form-arrow-trigger',

	shadow : 'sides',

	listAlign : 'tl-bl?',

	maxHeight : 300,

	minHeight : 90,

	triggerAction : 'query',

	minChars : 4,

	autoSelect : true,

	typeAhead : false,

	queryDelay : 500,

	pageSize : 0,

	selectOnFocus : false,

	queryParam : 'query',

	loadingText : 'Loading...',

	resizable : false,

	handleHeight : 8,

	allQuery: '',

	mode: 'remote',

	minListWidth : 70,

	forceSelection : false,

	typeAheadDelay : 250,



	lazyInit : true,


	clearFilterOnReset : true,


	submitValue: undefined,




	initComponent : function(){
		Ext.form.ComboBox.superclass.initComponent.call(this);
		this.addEvents(

			'expand',

			'collapse',


			'beforeselect',

			'select',

			'beforequery'
			);
		if(this.transform){
			var s = Ext.getDom(this.transform);
			if(!this.hiddenName){
				this.hiddenName = s.name;
			}
			if(!this.store){
				this.mode = 'local';
				var d = [], opts = s.options;
				for(var i = 0, len = opts.length;i < len; i++){
					var o = opts[i],
					value = (o.hasAttribute ? o.hasAttribute('value') : o.getAttributeNode('value').specified) ? o.value : o.text;
					if(o.selected && Ext.isEmpty(this.value, true)) {
						this.value = value;
					}
					d.push([value, o.text]);
				}
				this.store = new Ext.data.ArrayStore({
					idIndex: 0,
					fields: ['value', 'text'],
					data : d,
					autoDestroy: true
				});
				this.valueField = 'value';
				this.displayField = 'text';
			}
			s.name = Ext.id();
			if(!this.lazyRender){
				this.target = true;
				this.el = Ext.DomHelper.insertBefore(s, this.autoCreate || this.defaultAutoCreate);
				this.render(this.el.parentNode, s);
			}
			Ext.removeNode(s);
		}

		else if(this.store){
			this.store = Ext.StoreMgr.lookup(this.store);
			if(this.store.autoCreated){
				this.displayField = this.valueField = 'field1';
				if(!this.store.expandData){
					this.displayField = 'field2';
				}
				this.mode = 'local';
			}
		}

		this.selectedIndex = -1;
		if(this.mode == 'local'){
			if(!Ext.isDefined(this.initialConfig.queryDelay)){
				this.queryDelay = 10;
			}
			if(!Ext.isDefined(this.initialConfig.minChars)){
				this.minChars = 0;
			}
		}
	},


	onRender : function(ct, position){
		if(this.hiddenName && !Ext.isDefined(this.submitValue)){
			this.submitValue = false;
		}
		Ext.form.ComboBox.superclass.onRender.call(this, ct, position);
		if(this.hiddenName){
			this.hiddenField = this.el.insertSibling({
				tag:'input',
				type:'hidden',
				name: this.hiddenName,
				id: (this.hiddenId || Ext.id())
				}, 'before', true);

		}
		if(Ext.isGecko){
			this.el.dom.setAttribute('autocomplete', 'off');
		}

		if(!this.lazyInit){
			this.initList();
		}else{
			this.on('focus', this.initList, this, {
				single: true
			});
		}
	},


	initValue : function(){
		Ext.form.ComboBox.superclass.initValue.call(this);
		if(this.hiddenField){
			this.hiddenField.value =
			Ext.value(Ext.isDefined(this.hiddenValue) ? this.hiddenValue : this.value, '');
		}
	},

	getParentZIndex : function(){
		var zindex;
		if (this.ownerCt){
			this.findParentBy(function(ct){
				zindex = parseInt(ct.getPositionEl().getStyle('z-index'), 10);
				return !!zindex;
			});
		}
		return zindex;
	},

	getZIndex : function(listParent){
		listParent = listParent || Ext.getDom(this.getListParent() || Ext.getBody());
		var zindex = parseInt(Ext.fly(listParent).getStyle('z-index'), 10);
		if(!zindex){
			zindex = this.getParentZIndex();
		}
		return (zindex || 12000) + 5;
	},


	initList : function(){
		if(!this.list){
			var cls = 'x-combo-list',
			listParent = Ext.getDom(this.getListParent() || Ext.getBody());

			this.list = new Ext.Layer({
				parentEl: listParent,
				shadow: this.shadow,
				cls: [cls, this.listClass].join(' '),
				constrain:false,
				zindex: this.getZIndex(listParent)
			});

			var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
			this.list.setSize(lw, 0);
			this.list.swallowEvent('mousewheel');
			this.assetHeight = 0;
			if(this.syncFont !== false){
				this.list.setStyle('font-size', this.el.getStyle('font-size'));
			}
			if(this.title){
				this.header = this.list.createChild({
					cls:cls+'-hd',
					html: this.title
					});
				this.assetHeight += this.header.getHeight();
			}

			this.innerList = this.list.createChild({
				cls:cls+'-inner'
				});
			this.mon(this.innerList, 'mouseover', this.onViewOver, this);
			this.mon(this.innerList, 'mousemove', this.onViewMove, this);
			this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));

			if(this.pageSize){
				this.footer = this.list.createChild({
					cls:cls+'-ft'
					});
				this.pageTb = new Ext.PagingToolbar({
					store: this.store,
					pageSize: this.pageSize,
					renderTo:this.footer
				});
				this.assetHeight += this.footer.getHeight();
			}

			if(!this.tpl){

				this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';

			}


			this.view = new Ext.DataView({
				applyTo: this.innerList,
				tpl: this.tpl,
				singleSelect: true,
				selectedClass: this.selectedClass,
				itemSelector: this.itemSelector || '.' + cls + '-item',
				emptyText: this.listEmptyText,
				deferEmptyText: false
			});

			this.mon(this.view, {
				containerclick : this.onViewClick,
				click : this.onViewClick,
				scope :this
			});

			this.bindStore(this.store, true);

			if(this.resizable){
				this.resizer = new Ext.Resizable(this.list,  {
					pinned:true,
					handles:'se'
				});
				this.mon(this.resizer, 'resize', function(r, w, h){
					this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
					this.listWidth = w;
					this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
					this.restrictHeight();
				}, this);

				this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
			}
		}
	},


	getListParent : function() {
		return document.body;
	},


	getStore : function(){
		return this.store;
	},


	bindStore : function(store, initial){
		if(this.store && !initial){
			if(this.store !== store && this.store.autoDestroy){
				this.store.destroy();
			}else{
				this.store.un('beforeload', this.onBeforeLoad, this);
				this.store.un('load', this.onLoad, this);
				this.store.un('exception', this.collapse, this);
			}
			if(!store){
				this.store = null;
				if(this.view){
					this.view.bindStore(null);
				}
				if(this.pageTb){
					this.pageTb.bindStore(null);
				}
			}
		}
		if(store){
			if(!initial) {
				this.lastQuery = null;
				if(this.pageTb) {
					this.pageTb.bindStore(store);
				}
			}

			this.store = Ext.StoreMgr.lookup(store);
			this.store.on({
				scope: this,
				beforeload: this.onBeforeLoad,
				load: this.onLoad,
				exception: this.collapse
			});

			if(this.view){
				this.view.bindStore(store);
			}
		}
	},

	reset : function(){
		if(this.clearFilterOnReset && this.mode == 'local'){
			this.store.clearFilter();
		}
		Ext.form.ComboBox.superclass.reset.call(this);
	},


	initEvents : function(){
		Ext.form.ComboBox.superclass.initEvents.call(this);


		this.keyNav = new Ext.KeyNav(this.el, {
			"up" : function(e){
				this.inKeyMode = true;
				this.selectPrev();
			},

			"down" : function(e){
				if(!this.isExpanded()){
					this.onTriggerClick();
				}else{
					this.inKeyMode = true;
					this.selectNext();
				}
			},

			"enter" : function(e){
				this.onViewClick();
			},

			"esc" : function(e){
				this.collapse();
			},

			"tab" : function(e){
				if (this.forceSelection === true) {
					this.collapse();
				} else {
					this.onViewClick(false);
				}
				return true;
			},

			scope : this,

			doRelay : function(e, h, hname){
				if(hname == 'down' || this.scope.isExpanded()){

					var relay = Ext.KeyNav.prototype.doRelay.apply(this, arguments);
					if(!Ext.isIE && Ext.EventManager.useKeydown){

						this.scope.fireKey(e);
					}
					return relay;
				}
				return true;
			},

			forceKeyDown : true,
			defaultEventAction: 'stopEvent'
		});
		this.queryDelay = Math.max(this.queryDelay || 10,
			this.mode == 'local' ? 10 : 250);
		this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
		if(this.typeAhead){
			this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
		}
		if(!this.enableKeyEvents){
			this.mon(this.el, 'keyup', this.onKeyUp, this);
		}
	},



	onDestroy : function(){
		if (this.dqTask){
			this.dqTask.cancel();
			this.dqTask = null;
		}
		this.bindStore(null);
		Ext.destroy(
			this.resizer,
			this.view,
			this.pageTb,
			this.list
			);
		Ext.destroyMembers(this, 'hiddenField');
		Ext.form.ComboBox.superclass.onDestroy.call(this);
	},


	fireKey : function(e){
		if (!this.isExpanded()) {
			Ext.form.ComboBox.superclass.fireKey.call(this, e);
		}
	},


	onResize : function(w, h){
		Ext.form.ComboBox.superclass.onResize.apply(this, arguments);
		if(!isNaN(w) && this.isVisible() && this.list){
			this.doResize(w);
		}else{
			this.bufferSize = w;
		}
	},

	doResize: function(w){
		if(!Ext.isDefined(this.listWidth)){
			var lw = Math.max(w, this.minListWidth);
			this.list.setWidth(lw);
			this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
		}
	},


	onEnable : function(){
		Ext.form.ComboBox.superclass.onEnable.apply(this, arguments);
		if(this.hiddenField){
			this.hiddenField.disabled = false;
		}
	},


	onDisable : function(){
		Ext.form.ComboBox.superclass.onDisable.apply(this, arguments);
		if(this.hiddenField){
			this.hiddenField.disabled = true;
		}
	},


	onBeforeLoad : function(){
		if(!this.hasFocus){
			return;
		}
		this.innerList.update(this.loadingText ?
			'<div class="loading-indicator">'+this.loadingText+'</div>' : '');
		this.restrictHeight();
		this.selectedIndex = -1;
	},


	onLoad : function(){
		if(!this.hasFocus){
			return;
		}
		if(this.store.getCount() > 0 || this.listEmptyText){
			this.expand();
			this.restrictHeight();
			if(this.lastQuery == this.allQuery){
				if(this.editable){
					this.el.dom.select();
				}

				if(this.autoSelect !== false && !this.selectByValue(this.value, true)){
					this.select(0, true);
				}
			}else{
				if(this.autoSelect !== false){
					this.selectNext();
				}
				if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
					this.taTask.delay(this.typeAheadDelay);
				}
			}
		}else{
			this.collapse();
		}

	},


	onTypeAhead : function(){
		if(this.store.getCount() > 0){
			var r = this.store.getAt(0);
			var newValue = r.data[this.displayField];
			var len = newValue.length;
			var selStart = this.getRawValue().length;
			if(selStart != len){
				this.setRawValue(newValue);
				this.selectText(selStart, newValue.length);
			}
		}
	},


	assertValue : function(){
		var val = this.getRawValue(),
		rec;

		if(this.valueField && Ext.isDefined(this.value)){
			rec = this.findRecord(this.valueField, this.value);
		}
		if(!rec || rec.get(this.displayField) != val){
			rec = this.findRecord(this.displayField, val);
		}
		if(!rec && this.forceSelection){
			if(val.length > 0 && val != this.emptyText){
				this.el.dom.value = Ext.value(this.lastSelectionText, '');
				this.applyEmptyText();
			}else{
				this.clearValue();
			}
		}else{
			if(rec && this.valueField){



				if (this.value == val){
					return;
				}
				val = rec.get(this.valueField || this.displayField);
			}
			this.setValue(val);
		}
	},


	onSelect : function(record, index){
		if(this.fireEvent('beforeselect', this, record, index) !== false){
			this.setValue(record.data[this.valueField || this.displayField]);
			this.collapse();
			this.fireEvent('select', this, record, index);
		}
	},


	getName: function(){
		var hf = this.hiddenField;
		return hf && hf.name ? hf.name : this.hiddenName || Ext.form.ComboBox.superclass.getName.call(this);
	},


	getValue : function(){
		if(this.valueField){
			return Ext.isDefined(this.value) ? this.value : '';
		}else{
			return Ext.form.ComboBox.superclass.getValue.call(this);
		}
	},


	clearValue : function(){
		if(this.hiddenField){
			this.hiddenField.value = '';
		}
		this.setRawValue('');
		this.lastSelectionText = '';
		this.applyEmptyText();
		this.value = '';
	},


	setValue : function(v){
		var text = v;
		if(this.valueField){
			var r = this.findRecord(this.valueField, v);
			if(r){
				text = r.data[this.displayField];
			}else if(Ext.isDefined(this.valueNotFoundText)){
				text = this.valueNotFoundText;
			}
		}
		this.lastSelectionText = text;
		if(this.hiddenField){
			this.hiddenField.value = Ext.value(v, '');
		}
		Ext.form.ComboBox.superclass.setValue.call(this, text);
		this.value = v;
		return this;
	},


	findRecord : function(prop, value){
		var record;
		if(this.store.getCount() > 0){
			this.store.each(function(r){
				if(r.data[prop] == value){
					record = r;
					return false;
				}
			});
		}
		return record;
	},


	onViewMove : function(e, t){
		this.inKeyMode = false;
	},


	onViewOver : function(e, t){
		if(this.inKeyMode){
			return;
		}
		var item = this.view.findItemFromChild(t);
		if(item){
			var index = this.view.indexOf(item);
			this.select(index, false);
		}
	},


	onViewClick : function(doFocus){
		var index = this.view.getSelectedIndexes()[0],
		s = this.store,
		r = s.getAt(index);
		if(r){
			this.onSelect(r, index);
		}else {
			this.collapse();
		}
		if(doFocus !== false){
			this.el.focus();
		}
	},



	restrictHeight : function(){
		this.innerList.dom.style.height = '';
		var inner = this.innerList.dom,
		pad = this.list.getFrameWidth('tb') + (this.resizable ? this.handleHeight : 0) + this.assetHeight,
		h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight),
		ha = this.getPosition()[1]-Ext.getBody().getScroll().top,
		hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height,
		space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadowOffset-pad-5;

		h = Math.min(h, space, this.maxHeight);

		this.innerList.setHeight(h);
		this.list.beginUpdate();
		this.list.setHeight(h+pad);
		this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
		this.list.endUpdate();
	},


	isExpanded : function(){
		return this.list && this.list.isVisible();
	},


	selectByValue : function(v, scrollIntoView){
		if(!Ext.isEmpty(v, true)){
			var r = this.findRecord(this.valueField || this.displayField, v);
			if(r){
				this.select(this.store.indexOf(r), scrollIntoView);
				return true;
			}
		}
		return false;
	},


	select : function(index, scrollIntoView){
		this.selectedIndex = index;
		this.view.select(index);
		if(scrollIntoView !== false){
			var el = this.view.getNode(index);
			if(el){
				this.innerList.scrollChildIntoView(el, false);
			}
		}

	},


	selectNext : function(){
		var ct = this.store.getCount();
		if(ct > 0){
			if(this.selectedIndex == -1){
				this.select(0);
			}else if(this.selectedIndex < ct-1){
				this.select(this.selectedIndex+1);
			}
		}
	},


	selectPrev : function(){
		var ct = this.store.getCount();
		if(ct > 0){
			if(this.selectedIndex == -1){
				this.select(0);
			}else if(this.selectedIndex !== 0){
				this.select(this.selectedIndex-1);
			}
		}
	},


	onKeyUp : function(e){
		var k = e.getKey();
		if(this.editable !== false && this.readOnly !== true && (k == e.BACKSPACE || !e.isSpecialKey())){

			this.lastKey = k;
			this.dqTask.delay(this.queryDelay);
		}
		Ext.form.ComboBox.superclass.onKeyUp.call(this, e);
	},


	validateBlur : function(){
		return !this.list || !this.list.isVisible();
	},


	initQuery : function(){
		this.doQuery(this.getRawValue());
	},


	beforeBlur : function(){
		this.assertValue();
	},


	postBlur  : function(){
		Ext.form.ComboBox.superclass.postBlur.call(this);
		this.collapse();
		this.inKeyMode = false;
	},


	doQuery : function(q, forceAll){
		q = Ext.isEmpty(q) ? '' : q;
		var qe = {
			query: q,
			forceAll: forceAll,
			combo: this,
			cancel:false
		};
		if(this.fireEvent('beforequery', qe)===false || qe.cancel){
			return false;
		}
		q = qe.query;
		forceAll = qe.forceAll;
		if(forceAll === true || (q.length >= this.minChars)){
			if(this.lastQuery !== q){
				this.lastQuery = q;
				if(this.mode == 'local'){
					this.selectedIndex = -1;
					if(forceAll){
						this.store.clearFilter();
					}else{
						this.store.filter(this.displayField, q);
					}
					this.onLoad();
				}else{
					this.store.baseParams[this.queryParam] = q;
					this.store.load({
						params: this.getParams(q)
					});
					this.expand();
				}
			}else{
				this.selectedIndex = -1;
				this.onLoad();
			}
		}
	},


	getParams : function(q){
		var params = {},
		paramNames = this.store.paramNames;
		if(this.pageSize){
			params[paramNames.start] = 0;
			params[paramNames.limit] = this.pageSize;
		}
		return params;
	},


	collapse : function(){
		if(!this.isExpanded()){
			return;
		}
		this.list.hide();
		Ext.getDoc().un('mousewheel', this.collapseIf, this);
		Ext.getDoc().un('mousedown', this.collapseIf, this);
		this.fireEvent('collapse', this);
	},


	collapseIf : function(e){
		if(!this.isDestroyed && !e.within(this.wrap) && !e.within(this.list)){
			this.collapse();
		}
	},


	expand : function(){
		if(this.isExpanded() || !this.hasFocus){
			return;
		}

		if(this.title || this.pageSize){
			this.assetHeight = 0;
			if(this.title){
				this.assetHeight += this.header.getHeight();
			}
			if(this.pageSize){
				this.assetHeight += this.footer.getHeight();
			}
		}

		if(this.bufferSize){
			this.doResize(this.bufferSize);
			delete this.bufferSize;
		}
		this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));


		this.list.setZIndex(this.getZIndex());
		this.list.show();
		if(Ext.isGecko2){
			this.innerList.setOverflow('auto');
		}
		this.mon(Ext.getDoc(), {
			scope: this,
			mousewheel: this.collapseIf,
			mousedown: this.collapseIf
		});
		this.fireEvent('expand', this);
	},




	onTriggerClick : function(){
		if(this.readOnly || this.disabled){
			return;
		}
		if(this.isExpanded()){
			this.collapse();
			this.el.focus();
		}else {
			this.onFocus({});
			if(this.triggerAction == 'all') {
				this.doQuery(this.allQuery, true);
			} else {
				this.doQuery(this.getRawValue());
			}
			this.el.focus();
		}
	}






});
Ext.reg('combo', Ext.form.ComboBox);

Ext.form.Checkbox = Ext.extend(Ext.form.Field,  {

	focusClass : undefined,

	fieldClass : 'x-form-field',

	checked : false,

	boxLabel: '&#160;',

	defaultAutoCreate : {
		tag: 'input',
		type: 'checkbox',
		autocomplete: 'off'
	},





	actionMode : 'wrap',


	initComponent : function(){
		Ext.form.Checkbox.superclass.initComponent.call(this);
		this.addEvents(

			'check'
			);
	},


	onResize : function(){
		Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
		if(!this.boxLabel && !this.fieldLabel){
			this.el.alignTo(this.wrap, 'c-c');
		}
	},


	initEvents : function(){
		Ext.form.Checkbox.superclass.initEvents.call(this);
		this.mon(this.el, {
			scope: this,
			click: this.onClick,
			change: this.onClick
		});
	},


	markInvalid : Ext.emptyFn,

	clearInvalid : Ext.emptyFn,


	onRender : function(ct, position){
		Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
		if(this.inputValue !== undefined){
			this.el.dom.value = this.inputValue;
		}
		this.wrap = this.el.wrap({
			cls: 'x-form-check-wrap'
		});
		if(this.boxLabel){
			this.wrap.createChild({
				tag: 'label',
				htmlFor: this.el.id,
				cls: 'x-form-cb-label',
				html: this.boxLabel
				});
		}
		if(this.checked){
			this.setValue(true);
		}else{
			this.checked = this.el.dom.checked;
		}

		if (Ext.isIE && !Ext.isStrict) {
			this.wrap.repaint();
		}
		this.resizeEl = this.positionEl = this.wrap;
	},


	onDestroy : function(){
		Ext.destroy(this.wrap);
		Ext.form.Checkbox.superclass.onDestroy.call(this);
	},


	initValue : function() {
		this.originalValue = this.getValue();
	},


	getValue : function(){
		if(this.rendered){
			return this.el.dom.checked;
		}
		return this.checked;
	},


	onClick : function(){
		if(this.el.dom.checked != this.checked){
			this.setValue(this.el.dom.checked);
		}
	},


	setValue : function(v){
		var checked = this.checked,
		inputVal = this.inputValue;

		this.checked = (v === true || v === 'true' || v == '1' || (inputVal ? v == inputVal : String(v).toLowerCase() == 'on'));
		if(this.rendered){
			this.el.dom.checked = this.checked;
			this.el.dom.defaultChecked = this.checked;
		}
		if(checked != this.checked){
			this.fireEvent('check', this, this.checked);
			if(this.handler){
				this.handler.call(this.scope || this, this, this.checked);
			}
		}
		return this;
	}
});
Ext.reg('checkbox', Ext.form.Checkbox);

Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {


	columns : 'auto',

	vertical : false,

	allowBlank : true,

	blankText : "You must select at least one item in this group",


	defaultType : 'checkbox',


	groupCls : 'x-form-check-group',


	initComponent: function(){
		this.addEvents(

			'change'
			);
		this.on('change', this.validate, this);
		Ext.form.CheckboxGroup.superclass.initComponent.call(this);
	},


	onRender : function(ct, position){
		if(!this.el){
			var panelCfg = {
				autoEl: {
					id: this.id
				},
				cls: this.groupCls,
				layout: 'column',
				renderTo: ct,
				bufferResize: false
			};
			var colCfg = {
				xtype: 'container',
				defaultType: this.defaultType,
				layout: 'form',
				defaults: {
					hideLabel: true,
					anchor: '100%'
				}
			};

			if(this.items[0].items){



				Ext.apply(panelCfg, {
					layoutConfig: {
						columns: this.items.length
						},
					defaults: this.defaults,
					items: this.items
				});
				for(var i=0, len=this.items.length; i<len; i++){
					Ext.applyIf(this.items[i], colCfg);
				}

			}else{




				var numCols, cols = [];

				if(typeof this.columns == 'string'){
					this.columns = this.items.length;
				}
				if(!Ext.isArray(this.columns)){
					var cs = [];
					for(var i=0; i<this.columns; i++){
						cs.push((100/this.columns)*.01);
					}
					this.columns = cs;
				}

				numCols = this.columns.length;


				for(var i=0; i<numCols; i++){
					var cc = Ext.apply({
						items:[]
					}, colCfg);
					cc[this.columns[i] <= 1 ? 'columnWidth' : 'width'] = this.columns[i];
					if(this.defaults){
						cc.defaults = Ext.apply(cc.defaults || {}, this.defaults);
					}
					cols.push(cc);
				};


				if(this.vertical){
					var rows = Math.ceil(this.items.length / numCols), ri = 0;
					for(var i=0, len=this.items.length; i<len; i++){
						if(i>0 && i%rows==0){
							ri++;
						}
						if(this.items[i].fieldLabel){
							this.items[i].hideLabel = false;
						}
						cols[ri].items.push(this.items[i]);
					};
				}else{
					for(var i=0, len=this.items.length; i<len; i++){
						var ci = i % numCols;
						if(this.items[i].fieldLabel){
							this.items[i].hideLabel = false;
						}
						cols[ci].items.push(this.items[i]);
					};
				}

				Ext.apply(panelCfg, {
					layoutConfig: {
						columns: numCols
					},
					items: cols
				});
			}

			this.panel = new Ext.Container(panelCfg);
			this.panel.ownerCt = this;
			this.el = this.panel.getEl();

			if(this.forId && this.itemCls){
				var l = this.el.up(this.itemCls).child('label', true);
				if(l){
					l.setAttribute('htmlFor', this.forId);
				}
			}

			var fields = this.panel.findBy(function(c){
				return c.isFormField;
			}, this);

			this.items = new Ext.util.MixedCollection();
			this.items.addAll(fields);
		}
		Ext.form.CheckboxGroup.superclass.onRender.call(this, ct, position);
	},

	initValue : function(){
		if(this.value){
			this.setValue.apply(this, this.buffered ? this.value : [this.value]);
			delete this.buffered;
			delete this.value;
		}
	},

	afterRender : function(){
		Ext.form.CheckboxGroup.superclass.afterRender.call(this);
		this.eachItem(function(item){
			item.on('check', this.fireChecked, this);
			item.inGroup = true;
		});
	},


	doLayout: function(){

		if(this.rendered){
			this.panel.forceLayout = this.ownerCt.forceLayout;
			this.panel.doLayout();
		}
	},


	fireChecked: function(){
		var arr = [];
		this.eachItem(function(item){
			if(item.checked){
				arr.push(item);
			}
		});
		this.fireEvent('change', this, arr);
	},


	getErrors: function() {
		var errors = Ext.form.CheckboxGroup.superclass.getErrors.apply(this, arguments);

		if (!this.allowBlank) {
			var blank = true;

			this.eachItem(function(f){
				if (f.checked) {
					return (blank = false);
				}
			});

			if (blank) errors.push(this.blankText);
		}

		return errors;
	},


	isDirty: function(){

		if (this.disabled || !this.rendered) {
			return false;
		}

		var dirty = false;

		this.eachItem(function(item){
			if(item.isDirty()){
				dirty = true;
				return false;
			}
		});

		return dirty;
	},


	setReadOnly : function(readOnly){
		if(this.rendered){
			this.eachItem(function(item){
				item.setReadOnly(readOnly);
			});
		}
		this.readOnly = readOnly;
	},


	onDisable : function(){
		this.eachItem(function(item){
			item.disable();
		});
	},


	onEnable : function(){
		this.eachItem(function(item){
			item.enable();
		});
	},


	onResize : function(w, h){
		this.panel.setSize(w, h);
		this.panel.doLayout();
	},


	reset : function(){
		if (this.originalValue) {

			this.eachItem(function(c){
				if(c.setValue){
					c.setValue(false);
					c.originalValue = c.getValue();
				}
			});


			this.resetOriginal = true;
			this.setValue(this.originalValue);
			delete this.resetOriginal;
		} else {
			this.eachItem(function(c){
				if(c.reset){
					c.reset();
				}
			});
		}


		(function() {
			this.clearInvalid();
		}).defer(50, this);
	},


	setValue: function(){
		if(this.rendered){
			this.onSetValue.apply(this, arguments);
		}else{
			this.buffered = true;
			this.value = arguments;
		}
		return this;
	},


	onSetValue: function(id, value){
		if(arguments.length == 1){
			if(Ext.isArray(id)){
				Ext.each(id, function(val, idx){
					if (Ext.isObject(val) && val.setValue){
						val.setValue(true);
						if (this.resetOriginal === true) {
							val.originalValue = val.getValue();
						}
					} else {
						var item = this.items.itemAt(idx);
						if(item){
							item.setValue(val);
						}
					}
				}, this);
			}else if(Ext.isObject(id)){

				for(var i in id){
					var f = this.getBox(i);
					if(f){
						f.setValue(id[i]);
					}
				}
			}else{
				this.setValueForItem(id);
			}
		}else{
			var f = this.getBox(id);
			if(f){
				f.setValue(value);
			}
		}
	},


	beforeDestroy: function(){
		Ext.destroy(this.panel);
		if (!this.rendered) {
			Ext.destroy(this.items);
		}
		Ext.form.CheckboxGroup.superclass.beforeDestroy.call(this);

	},

	setValueForItem : function(val){
		val = String(val).split(',');
		this.eachItem(function(item){
			if(val.indexOf(item.inputValue)> -1){
				item.setValue(true);
			}
		});
	},


	getBox : function(id){
		var box = null;
		this.eachItem(function(f){
			if(id == f || f.dataIndex == id || f.id == id || f.getName() == id){
				box = f;
				return false;
			}
		});
		return box;
	},


	getValue : function(){
		var out = [];
		this.eachItem(function(item){
			if(item.checked){
				out.push(item);
			}
		});
		return out;
	},


	eachItem: function(fn, scope) {
		if(this.items && this.items.each){
			this.items.each(fn, scope || this);
		}
	},




	getRawValue : Ext.emptyFn,


	setRawValue : Ext.emptyFn

});

Ext.reg('checkboxgroup', Ext.form.CheckboxGroup);

Ext.form.CompositeField = Ext.extend(Ext.form.Field, {


	defaultMargins: '0 5 0 0',


	skipLastItemMargin: true,


	isComposite: true,


	combineErrors: true,


	labelConnector: ', ',





	initComponent: function() {
		var labels = [],
		items  = this.items,
		item;

		for (var i=0, j = items.length; i < j; i++) {
			item = items[i];

			if (!Ext.isEmpty(item.ref)){
				item.ref = '../' + item.ref;
			}

			labels.push(item.fieldLabel);


			Ext.applyIf(item, this.defaults);


			if (!(i == j - 1 && this.skipLastItemMargin)) {
				Ext.applyIf(item, {
					margins: this.defaultMargins
					});
			}
		}

		this.fieldLabel = this.fieldLabel || this.buildLabel(labels);


		this.fieldErrors = new Ext.util.MixedCollection(true, function(item) {
			return item.field;
		});

		this.fieldErrors.on({
			scope  : this,
			add    : this.updateInvalidMark,
			remove : this.updateInvalidMark,
			replace: this.updateInvalidMark
		});

		Ext.form.CompositeField.superclass.initComponent.apply(this, arguments);

		this.innerCt = new Ext.Container({
			layout  : 'hbox',
			items   : this.items,
			cls     : 'x-form-composite',
			defaultMargins: '0 3 0 0',
			ownerCt: this
		});
		this.innerCt.ownerCt = undefined;

		var fields = this.innerCt.findBy(function(c) {
			return c.isFormField;
		}, this);


		this.items = new Ext.util.MixedCollection();
		this.items.addAll(fields);

	},


	onRender: function(ct, position) {
		if (!this.el) {

			var innerCt = this.innerCt;
			innerCt.render(ct);

			this.el = innerCt.getEl();



			if (this.combineErrors) {
				this.eachItem(function(field) {
					Ext.apply(field, {
						markInvalid : this.onFieldMarkInvalid.createDelegate(this, [field], 0),
						clearInvalid: this.onFieldClearInvalid.createDelegate(this, [field], 0)
					});
				});
			}


			var l = this.el.parent().parent().child('label', true);
			if (l) {
				l.setAttribute('for', this.items.items[0].id);
			}
		}

		Ext.form.CompositeField.superclass.onRender.apply(this, arguments);
	},


	onFieldMarkInvalid: function(field, message) {
		var name  = field.getName(),
		error = {
			field: name,
			errorName: field.fieldLabel || name,
			error: message
		};

		this.fieldErrors.replace(name, error);

		field.el.addClass(field.invalidClass);
	},


	onFieldClearInvalid: function(field) {
		this.fieldErrors.removeKey(field.getName());

		field.el.removeClass(field.invalidClass);
	},


	updateInvalidMark: function() {
		var ieStrict = Ext.isIE6 && Ext.isStrict;

		if (this.fieldErrors.length == 0) {
			this.clearInvalid();


			if (ieStrict) {
				this.clearInvalid.defer(50, this);
			}
		} else {
			var message = this.buildCombinedErrorMessage(this.fieldErrors.items);

			this.sortErrors();
			this.markInvalid(message);


			if (ieStrict) {
				this.markInvalid(message);
			}
		}
	},


	validateValue: function() {
		var valid = true;

		this.eachItem(function(field) {
			if (!field.isValid()) valid = false;
		});

		return valid;
	},


	buildCombinedErrorMessage: function(errors) {
		var combined = [],
		error;

		for (var i = 0, j = errors.length; i < j; i++) {
			error = errors[i];

			combined.push(String.format("{0}: {1}", error.errorName, error.error));
		}

		return combined.join("<br />");
	},


	sortErrors: function() {
		var fields = this.items;

		this.fieldErrors.sort("ASC", function(a, b) {
			var findByName = function(key) {
				return function(field) {
					return field.getName() == key;
				};
			};

			var aIndex = fields.findIndexBy(findByName(a.field)),
			bIndex = fields.findIndexBy(findByName(b.field));

			return aIndex < bIndex ? -1 : 1;
		});
	},


	reset: function() {
		this.eachItem(function(item) {
			item.reset();
		});



		(function() {
			this.clearInvalid();
		}).defer(50, this);
	},


	clearInvalidChildren: function() {
		this.eachItem(function(item) {
			item.clearInvalid();
		});
	},


	buildLabel: function(segments) {
		return Ext.clean(segments).join(this.labelConnector);
	},


	isDirty: function(){

		if (this.disabled || !this.rendered) {
			return false;
		}

		var dirty = false;
		this.eachItem(function(item){
			if(item.isDirty()){
				dirty = true;
				return false;
			}
		});
		return dirty;
	},


	eachItem: function(fn, scope) {
		if(this.items && this.items.each){
			this.items.each(fn, scope || this);
		}
	},


	onResize: function(adjWidth, adjHeight, rawWidth, rawHeight) {
		var innerCt = this.innerCt;

		if (this.rendered && innerCt.rendered) {
			innerCt.setSize(adjWidth, adjHeight);
		}

		Ext.form.CompositeField.superclass.onResize.apply(this, arguments);
	},


	doLayout: function(shallow, force) {
		if (this.rendered) {
			var innerCt = this.innerCt;

			innerCt.forceLayout = this.ownerCt.forceLayout;
			innerCt.doLayout(shallow, force);
		}
	},


	beforeDestroy: function(){
		Ext.destroy(this.innerCt);

		Ext.form.CompositeField.superclass.beforeDestroy.call(this);
	},


	setReadOnly : function(readOnly) {
		if (readOnly == undefined) {
			readOnly = true;
		}
		readOnly = !!readOnly;

		if(this.rendered){
			this.eachItem(function(item){
				item.setReadOnly(readOnly);
			});
		}
		this.readOnly = readOnly;
	},

	onShow : function() {
		Ext.form.CompositeField.superclass.onShow.call(this);
		this.doLayout();
	},


	onDisable : function(){
		this.eachItem(function(item){
			item.disable();
		});
	},


	onEnable : function(){
		this.eachItem(function(item){
			item.enable();
		});
	}
});

Ext.reg('compositefield', Ext.form.CompositeField);
Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
	inputType: 'radio',


	markInvalid : Ext.emptyFn,

	clearInvalid : Ext.emptyFn,


	getGroupValue : function(){
		var p = this.el.up('form') || Ext.getBody();
		var c = p.child('input[name='+this.el.dom.name+']:checked', true);
		return c ? c.value : null;
	},


	setValue : function(v){
		var checkEl,
		els,
		radio;
		if (typeof v == 'boolean') {
			Ext.form.Radio.superclass.setValue.call(this, v);
		} else if (this.rendered) {
			checkEl = this.getCheckEl();
			radio = checkEl.child('input[name=' + this.el.dom.name + '][value=' + v + ']', true);
			if(radio){
				Ext.getCmp(radio.id).setValue(true);
			}
		}
		if(this.rendered && this.checked){
			checkEl = checkEl || this.getCheckEl();
			els = this.getCheckEl().select('input[name=' + this.el.dom.name + ']');
			els.each(function(el){
				if(el.dom.id != this.id){
					Ext.getCmp(el.dom.id).setValue(false);
				}
			}, this);
		}
		return this;
	},


	getCheckEl: function(){
		if(this.inGroup){
			return this.el.up('.x-form-radio-group');
		}
		return this.el.up('form') || Ext.getBody();
	}
});
Ext.reg('radio', Ext.form.Radio);

Ext.form.RadioGroup = Ext.extend(Ext.form.CheckboxGroup, {


	allowBlank : true,

	blankText : 'You must select one item in this group',


	defaultType : 'radio',


	groupCls : 'x-form-radio-group',




	getValue : function(){
		var out = null;
		this.eachItem(function(item){
			if(item.checked){
				out = item;
				return false;
			}
		});
		return out;
	},


	onSetValue : function(id, value){
		if(arguments.length > 1){
			var f = this.getBox(id);
			if(f){
				f.setValue(value);
				if(f.checked){
					this.eachItem(function(item){
						if (item !== f){
							item.setValue(false);
						}
					});
				}
			}
		}else{
			this.setValueForItem(id);
		}
	},

	setValueForItem : function(val){
		val = String(val).split(',')[0];
		this.eachItem(function(item){
			item.setValue(val == item.inputValue);
		});
	},


	fireChecked : function(){
		if(!this.checkTask){
			this.checkTask = new Ext.util.DelayedTask(this.bufferChecked, this);
		}
		this.checkTask.delay(10);
	},


	bufferChecked : function(){
		var out = null;
		this.eachItem(function(item){
			if(item.checked){
				out = item;
				return false;
			}
		});
		this.fireEvent('change', this, out);
	},

	onDestroy : function(){
		if(this.checkTask){
			this.checkTask.cancel();
			this.checkTask = null;
		}
		Ext.form.RadioGroup.superclass.onDestroy.call(this);
	}

});

Ext.reg('radiogroup', Ext.form.RadioGroup);

Ext.form.Hidden = Ext.extend(Ext.form.Field, {

	inputType : 'hidden',

	shouldLayout: false,


	onRender : function(){
		Ext.form.Hidden.superclass.onRender.apply(this, arguments);
	},


	initEvents : function(){
		this.originalValue = this.getValue();
	},


	setSize : Ext.emptyFn,
	setWidth : Ext.emptyFn,
	setHeight : Ext.emptyFn,
	setPosition : Ext.emptyFn,
	setPagePosition : Ext.emptyFn,
	markInvalid : Ext.emptyFn,
	clearInvalid : Ext.emptyFn
});
Ext.reg('hidden', Ext.form.Hidden);
Ext.form.BasicForm = Ext.extend(Ext.util.Observable, {

	constructor: function(el, config){
		Ext.apply(this, config);
		if(Ext.isString(this.paramOrder)){
			this.paramOrder = this.paramOrder.split(/[\s,|]/);
		}

		this.items = new Ext.util.MixedCollection(false, function(o){
			return o.getItemId();
		});
		this.addEvents(

			'beforeaction',

			'actionfailed',

			'actioncomplete'
			);

		if(el){
			this.initEl(el);
		}
		Ext.form.BasicForm.superclass.constructor.call(this);
	},








	timeout: 30,




	paramOrder: undefined,


	paramsAsHash: false,


	waitTitle: 'Please Wait...',


	activeAction : null,


	trackResetOnLoad : false,





	initEl : function(el){
		this.el = Ext.get(el);
		this.id = this.el.id || Ext.id();
		if(!this.standardSubmit){
			this.el.on('submit', this.onSubmit, this);
		}
		this.el.addClass('x-form');
	},


	getEl: function(){
		return this.el;
	},


	onSubmit : function(e){
		e.stopEvent();
	},


	destroy: function(bound){
		if(bound !== true){
			this.items.each(function(f){
				Ext.destroy(f);
			});
			Ext.destroy(this.el);
		}
		this.items.clear();
		this.purgeListeners();
	},


	isValid : function(){
		var valid = true;
		this.items.each(function(f){
			if(!f.validate()){
				valid = false;
			}
		});
		return valid;
	},


	isDirty : function(){
		var dirty = false;
		this.items.each(function(f){
			if(f.isDirty()){
				dirty = true;
				return false;
			}
		});
		return dirty;
	},


	doAction : function(action, options){
		if(Ext.isString(action)){
			action = new Ext.form.Action.ACTION_TYPES[action](this, options);
		}
		if(this.fireEvent('beforeaction', this, action) !== false){
			this.beforeAction(action);
			action.run.defer(100, action);
		}
		return this;
	},


	submit : function(options){
		options = options || {};
		if(this.standardSubmit){
			var v = options.clientValidation === false || this.isValid();
			if(v){
				var el = this.el.dom;
				if(this.url && Ext.isEmpty(el.action)){
					el.action = this.url;
				}
				el.submit();
			}
			return v;
		}
		var submitAction = String.format('{0}submit', this.api ? 'direct' : '');
		this.doAction(submitAction, options);
		return this;
	},


	load : function(options){
		var loadAction = String.format('{0}load', this.api ? 'direct' : '');
		this.doAction(loadAction, options);
		return this;
	},


	updateRecord : function(record){
		record.beginEdit();
		var fs = record.fields,
		field,
		value;
		fs.each(function(f){
			field = this.findField(f.name);
			if(field){
				value = field.getValue();
				if (typeof value != undefined && value.getGroupValue) {
					value = value.getGroupValue();
				} else if ( field.eachItem ) {
					value = [];
					field.eachItem(function(item){
						value.push(item.getValue());
					});
				}
				record.set(f.name, value);
			}
		}, this);
		record.endEdit();
		return this;
	},


	loadRecord : function(record){
		this.setValues(record.data);
		return this;
	},


	beforeAction : function(action){

		this.items.each(function(f){
			if(f.isFormField && f.syncValue){
				f.syncValue();
			}
		});
		var o = action.options;
		if(o.waitMsg){
			if(this.waitMsgTarget === true){
				this.el.mask(o.waitMsg, 'x-mask-loading');
			}else if(this.waitMsgTarget){
				this.waitMsgTarget = Ext.get(this.waitMsgTarget);
				this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading');
			}else{
				Ext.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle);
			}
		}
	},


	afterAction : function(action, success){
		this.activeAction = null;
		var o = action.options;
		if(o.waitMsg){
			if(this.waitMsgTarget === true){
				this.el.unmask();
			}else if(this.waitMsgTarget){
				this.waitMsgTarget.unmask();
			}else{
				Ext.MessageBox.updateProgress(1);
				Ext.MessageBox.hide();
			}
		}
		if(success){
			if(o.reset){
				this.reset();
			}
			Ext.callback(o.success, o.scope, [this, action]);
			this.fireEvent('actioncomplete', this, action);
		}else{
			Ext.callback(o.failure, o.scope, [this, action]);
			this.fireEvent('actionfailed', this, action);
		}
	},


	findField : function(id) {
		var field = this.items.get(id);

		if (!Ext.isObject(field)) {

			var findMatchingField = function(f) {
				if (f.isFormField) {
					if (f.dataIndex == id || f.id == id || f.getName() == id) {
						field = f;
						return false;
					} else if (f.isComposite) {
						return f.items.each(findMatchingField);
					} else if (f instanceof Ext.form.CheckboxGroup && f.rendered) {
						return f.eachItem(findMatchingField);
					}
				}
			};

			this.items.each(findMatchingField);
		}
		return field || null;
	},



	markInvalid : function(errors){
		if (Ext.isArray(errors)) {
			for(var i = 0, len = errors.length; i < len; i++){
				var fieldError = errors[i];
				var f = this.findField(fieldError.id);
				if(f){
					f.markInvalid(fieldError.msg);
				}
			}
		} else {
			var field, id;
			for(id in errors){
				if(!Ext.isFunction(errors[id]) && (field = this.findField(id))){
					field.markInvalid(errors[id]);
				}
			}
		}

		return this;
	},


	setValues : function(values){
		if(Ext.isArray(values)){
			for(var i = 0, len = values.length; i < len; i++){
				var v = values[i];
				var f = this.findField(v.id);
				if(f){
					f.setValue(v.value);
					if(this.trackResetOnLoad){
						f.originalValue = f.getValue();
					}
				}
			}
		}else{
			var field, id;
			for(id in values){
				if(!Ext.isFunction(values[id]) && (field = this.findField(id))){
					field.setValue(values[id]);
					if(this.trackResetOnLoad){
						field.originalValue = field.getValue();
					}
				}
			}
		}
		return this;
	},


	getValues : function(asString){
		var fs = Ext.lib.Ajax.serializeForm(this.el.dom);
		if(asString === true){
			return fs;
		}
		return Ext.urlDecode(fs);
	},


	getFieldValues : function(dirtyOnly){
		var o = {},
		n,
		key,
		val;
		this.items.each(function(f) {
			if (!f.disabled && (dirtyOnly !== true || f.isDirty())) {
				n = f.getName();
				key = o[n];
				val = f.getValue();

				if(Ext.isDefined(key)){
					if(Ext.isArray(key)){
						o[n].push(val);
					}else{
						o[n] = [key, val];
					}
				}else{
					o[n] = val;
				}
			}
		});
		return o;
	},


	clearInvalid : function(){
		this.items.each(function(f){
			f.clearInvalid();
		});
		return this;
	},


	reset : function(){
		this.items.each(function(f){
			f.reset();
		});
		return this;
	},


	add : function(){
		this.items.addAll(Array.prototype.slice.call(arguments, 0));
		return this;
	},


	remove : function(field){
		this.items.remove(field);
		return this;
	},


	cleanDestroyed : function() {
		this.items.filterBy(function(o) {
			return !!o.isDestroyed;
		}).each(this.remove, this);
	},


	render : function(){
		this.items.each(function(f){
			if(f.isFormField && !f.rendered && document.getElementById(f.id)){
				f.applyToMarkup(f.id);
			}
		});
		return this;
	},


	applyToFields : function(o){
		this.items.each(function(f){
			Ext.apply(f, o);
		});
		return this;
	},


	applyIfToFields : function(o){
		this.items.each(function(f){
			Ext.applyIf(f, o);
		});
		return this;
	},

	callFieldMethod : function(fnName, args){
		args = args || [];
		this.items.each(function(f){
			if(Ext.isFunction(f[fnName])){
				f[fnName].apply(f, args);
			}
		});
		return this;
	}
});


Ext.BasicForm = Ext.form.BasicForm;

Ext.FormPanel = Ext.extend(Ext.Panel, {










	minButtonWidth : 75,


	labelAlign : 'left',


	monitorValid : false,


	monitorPoll : 200,


	layout : 'form',


	initComponent : function(){
		this.form = this.createForm();
		Ext.FormPanel.superclass.initComponent.call(this);

		this.bodyCfg = {
			tag: 'form',
			cls: this.baseCls + '-body',
			method : this.method || 'POST',
			id : this.formId || Ext.id()
		};
		if(this.fileUpload) {
			this.bodyCfg.enctype = 'multipart/form-data';
		}
		this.initItems();

		this.addEvents(

			'clientvalidation'
			);

		this.relayEvents(this.form, ['beforeaction', 'actionfailed', 'actioncomplete']);
	},


	createForm : function(){
		var config = Ext.applyIf({
			listeners: {}
		}, this.initialConfig);
	return new Ext.form.BasicForm(null, config);
},


initFields : function(){
	var f = this.form;
	var formPanel = this;
	var fn = function(c){
		if(formPanel.isField(c)){
			f.add(c);
		}else if(c.findBy && c != formPanel){
			formPanel.applySettings(c);

			if(c.items && c.items.each){
				c.items.each(fn, this);
			}
		}
	};
	this.items.each(fn, this);
},


applySettings: function(c){
	var ct = c.ownerCt;
	Ext.applyIf(c, {
		labelAlign: ct.labelAlign,
		labelWidth: ct.labelWidth,
		itemCls: ct.itemCls
	});
},


getLayoutTarget : function(){
	return this.form.el;
},


getForm : function(){
	return this.form;
},


onRender : function(ct, position){
	this.initFields();
	Ext.FormPanel.superclass.onRender.call(this, ct, position);
	this.form.initEl(this.body);
},


beforeDestroy : function(){
	this.stopMonitoring();
	this.form.destroy(true);
	Ext.FormPanel.superclass.beforeDestroy.call(this);
},


isField : function(c) {
	return !!c.setValue && !!c.getValue && !!c.markInvalid && !!c.clearInvalid;
},


initEvents : function(){
	Ext.FormPanel.superclass.initEvents.call(this);

	this.on({
		scope: this,
		add: this.onAddEvent,
		remove: this.onRemoveEvent
	});
	if(this.monitorValid){
		this.startMonitoring();
	}
},


onAdd: function(c){
	Ext.FormPanel.superclass.onAdd.call(this, c);
	this.processAdd(c);
},


onAddEvent: function(ct, c){
	if(ct !== this){
		this.processAdd(c);
	}
},


processAdd : function(c){

	if(this.isField(c)){
		this.form.add(c);

	}else if(c.findBy){
		this.applySettings(c);
		this.form.add.apply(this.form, c.findBy(this.isField));
	}
},


onRemove: function(c){
	Ext.FormPanel.superclass.onRemove.call(this, c);
	this.processRemove(c);
},

onRemoveEvent: function(ct, c){
	if(ct !== this){
		this.processRemove(c);
	}
},


processRemove: function(c){
	if(!this.destroying){

		if(this.isField(c)){
			this.form.remove(c);

		}else if (c.findBy){
			Ext.each(c.findBy(this.isField), this.form.remove, this.form);

			this.form.cleanDestroyed();
		}
	}
},


startMonitoring : function(){
	if(!this.validTask){
		this.validTask = new Ext.util.TaskRunner();
		this.validTask.start({
			run : this.bindHandler,
			interval : this.monitorPoll || 200,
			scope: this
		});
	}
},


stopMonitoring : function(){
	if(this.validTask){
		this.validTask.stopAll();
		this.validTask = null;
	}
},


load : function(){
	this.form.load.apply(this.form, arguments);
},


onDisable : function(){
	Ext.FormPanel.superclass.onDisable.call(this);
	if(this.form){
		this.form.items.each(function(){
			this.disable();
		});
	}
},


onEnable : function(){
	Ext.FormPanel.superclass.onEnable.call(this);
	if(this.form){
		this.form.items.each(function(){
			this.enable();
		});
	}
},


bindHandler : function(){
	var valid = true;
	this.form.items.each(function(f){
		if(!f.isValid(true)){
			valid = false;
			return false;
		}
	});
	if(this.fbar){
		var fitems = this.fbar.items.items;
		for(var i = 0, len = fitems.length; i < len; i++){
			var btn = fitems[i];
			if(btn.formBind === true && btn.disabled === valid){
				btn.setDisabled(!valid);
			}
		}
	}
	this.fireEvent('clientvalidation', this, valid);
}
});
Ext.reg('form', Ext.FormPanel);

Ext.form.FormPanel = Ext.FormPanel;

Ext.form.FieldSet = Ext.extend(Ext.Panel, {






	baseCls : 'x-fieldset',

	layout : 'form',

	animCollapse : false,


	onRender : function(ct, position){
		if(!this.el){
			this.el = document.createElement('fieldset');
			this.el.id = this.id;
			if (this.title || this.header || this.checkboxToggle) {
				this.el.appendChild(document.createElement('legend')).className = this.baseCls + '-header';
			}
		}

		Ext.form.FieldSet.superclass.onRender.call(this, ct, position);

		if(this.checkboxToggle){
			var o = typeof this.checkboxToggle == 'object' ?
			this.checkboxToggle :
			{
				tag: 'input',
				type: 'checkbox',
				name: this.checkboxName || this.id+'-checkbox'
				};
			this.checkbox = this.header.insertFirst(o);
			this.checkbox.dom.checked = !this.collapsed;
			this.mon(this.checkbox, 'click', this.onCheckClick, this);
		}
	},


	onCollapse : function(doAnim, animArg){
		if(this.checkbox){
			this.checkbox.dom.checked = false;
		}
		Ext.form.FieldSet.superclass.onCollapse.call(this, doAnim, animArg);

	},


	onExpand : function(doAnim, animArg){
		if(this.checkbox){
			this.checkbox.dom.checked = true;
		}
		Ext.form.FieldSet.superclass.onExpand.call(this, doAnim, animArg);
	},


	onCheckClick : function(){
		this[this.checkbox.dom.checked ? 'expand' : 'collapse']();
	}



































});
Ext.reg('fieldset', Ext.form.FieldSet);

Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {

	enableFormat : true,

	enableFontSize : true,

	enableColors : true,

	enableAlignments : true,

	enableLists : true,

	enableSourceEdit : true,

	enableLinks : true,

	enableFont : true,

	createLinkText : 'Please enter the URL for the link:',

	defaultLinkValue : 'http:/'+'/',

	fontFamilies : [
	'Arial',
	'Courier New',
	'Tahoma',
	'Times New Roman',
	'Verdana'
	],
	defaultFont: 'tahoma',

	defaultValue: (Ext.isOpera || Ext.isIE6) ? '&#160;' : '&#8203;',


	actionMode: 'wrap',
	validationEvent : false,
	deferHeight: true,
	initialized : false,
	activated : false,
	sourceEditMode : false,
	onFocus : Ext.emptyFn,
	iframePad:3,
	hideMode:'offsets',
	defaultAutoCreate : {
		tag: "textarea",
		style:"width:500px;height:300px;",
		autocomplete: "off"
	},


	initComponent : function(){
		this.addEvents(

			'initialize',

			'activate',

			'beforesync',

			'beforepush',

			'sync',

			'push',

			'editmodechange'
			);
		Ext.form.HtmlEditor.superclass.initComponent.call(this);
	},


	createFontOptions : function(){
		var buf = [], fs = this.fontFamilies, ff, lc;
		for(var i = 0, len = fs.length; i< len; i++){
			ff = fs[i];
			lc = ff.toLowerCase();
			buf.push(
				'<option value="',lc,'" style="font-family:',ff,';"',
				(this.defaultFont == lc ? ' selected="true">' : '>'),
				ff,
				'</option>'
				);
		}
		return buf.join('');
	},


	createToolbar : function(editor){
		var items = [];
		var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled();


		function btn(id, toggle, handler){
			return {
				itemId : id,
				cls : 'x-btn-icon',
				iconCls: 'x-edit-'+id,
				enableToggle:toggle !== false,
				scope: editor,
				handler:handler||editor.relayBtnCmd,
				clickEvent:'mousedown',
				tooltip: tipsEnabled ? editor.buttonTips[id] || undefined : undefined,
				overflowText: editor.buttonTips[id].title || undefined,
				tabIndex:-1
			};
		}


		if(this.enableFont && !Ext.isSafari2){
			var fontSelectItem = new Ext.Toolbar.Item({
				autoEl: {
					tag:'select',
					cls:'x-font-select',
					html: this.createFontOptions()
				}
			});

			items.push(
				fontSelectItem,
				'-'
				);
		}

		if(this.enableFormat){
			items.push(
				btn('bold'),
				btn('italic'),
				btn('underline')
				);
		}

		if(this.enableFontSize){
			items.push(
				'-',
				btn('increasefontsize', false, this.adjustFont),
				btn('decreasefontsize', false, this.adjustFont)
				);
		}

		if(this.enableColors){
			items.push(
				'-', {
					itemId:'forecolor',
					cls:'x-btn-icon',
					iconCls: 'x-edit-forecolor',
					clickEvent:'mousedown',
					tooltip: tipsEnabled ? editor.buttonTips.forecolor || undefined : undefined,
					tabIndex:-1,
					menu : new Ext.menu.ColorMenu({
						allowReselect: true,
						focus: Ext.emptyFn,
						value:'000000',
						plain:true,
						listeners: {
							scope: this,
							select: function(cp, color){
								this.execCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
								this.deferFocus();
							}
						},
						clickEvent:'mousedown'
					})
				}, {
					itemId:'backcolor',
					cls:'x-btn-icon',
					iconCls: 'x-edit-backcolor',
					clickEvent:'mousedown',
					tooltip: tipsEnabled ? editor.buttonTips.backcolor || undefined : undefined,
					tabIndex:-1,
					menu : new Ext.menu.ColorMenu({
						focus: Ext.emptyFn,
						value:'FFFFFF',
						plain:true,
						allowReselect: true,
						listeners: {
							scope: this,
							select: function(cp, color){
								if(Ext.isGecko){
									this.execCmd('useCSS', false);
									this.execCmd('hilitecolor', color);
									this.execCmd('useCSS', true);
									this.deferFocus();
								}else{
									this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
									this.deferFocus();
								}
							}
						},
						clickEvent:'mousedown'
					})
				}
				);
		}

		if(this.enableAlignments){
			items.push(
				'-',
				btn('justifyleft'),
				btn('justifycenter'),
				btn('justifyright')
				);
		}

		if(!Ext.isSafari2){
			if(this.enableLinks){
				items.push(
					'-',
					btn('createlink', false, this.createLink)
					);
			}

			if(this.enableLists){
				items.push(
					'-',
					btn('insertorderedlist'),
					btn('insertunorderedlist')
					);
			}
			if(this.enableSourceEdit){
				items.push(
					'-',
					btn('sourceedit', true, function(btn){
						this.toggleSourceEdit(!this.sourceEditMode);
					})
					);
			}
		}


		var tb = new Ext.Toolbar({
			renderTo: this.wrap.dom.firstChild,
			items: items
		});

		if (fontSelectItem) {
			this.fontSelect = fontSelectItem.el;

			this.mon(this.fontSelect, 'change', function(){
				var font = this.fontSelect.dom.value;
				this.relayCmd('fontname', font);
				this.deferFocus();
			}, this);
		}


		this.mon(tb.el, 'click', function(e){
			e.preventDefault();
		});

		this.tb = tb;
		this.tb.doLayout();
	},

	onDisable: function(){
		this.wrap.mask();
		Ext.form.HtmlEditor.superclass.onDisable.call(this);
	},

	onEnable: function(){
		this.wrap.unmask();
		Ext.form.HtmlEditor.superclass.onEnable.call(this);
	},

	setReadOnly: function(readOnly){

		Ext.form.HtmlEditor.superclass.setReadOnly.call(this, readOnly);
		if(this.initialized){
			if(Ext.isIE){
				this.getEditorBody().contentEditable = !readOnly;
			}else{
				this.setDesignMode(!readOnly);
			}
			var bd = this.getEditorBody();
			if(bd){
				bd.style.cursor = this.readOnly ? 'default' : 'text';
			}
			this.disableItems(readOnly);
		}
	},


	getDocMarkup : function(){
		var h = Ext.fly(this.iframe).getHeight() - this.iframePad * 2;
		return String.format('<html><head><style type="text/css">body{border: 0; margin: 0; padding: {0}px; height: {1}px; cursor: text}</style></head><body></body></html>', this.iframePad, h);
	},


	getEditorBody : function(){
		var doc = this.getDoc();
		return doc.body || doc.documentElement;
	},


	getDoc : function(){
		return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document);
	},


	getWin : function(){
		return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name];
	},


	onRender : function(ct, position){
		Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);
		this.el.dom.style.border = '0 none';
		this.el.dom.setAttribute('tabIndex', -1);
		this.el.addClass('x-hidden');
		if(Ext.isIE){
			this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;');
		}
		this.wrap = this.el.wrap({
			cls:'x-html-editor-wrap',
			cn:{
				cls:'x-html-editor-tb'
			}
		});

		this.createToolbar(this);

		this.disableItems(true);

		this.tb.doLayout();

		this.createIFrame();

		if(!this.width){
			var sz = this.el.getSize();
			this.setSize(sz.width, this.height || sz.height);
		}
		this.resizeEl = this.positionEl = this.wrap;
	},

	createIFrame: function(){
		var iframe = document.createElement('iframe');
		iframe.name = Ext.id();
		iframe.frameBorder = '0';
		iframe.style.overflow = 'auto';
		iframe.src = Ext.SSL_SECURE_URL;

		this.wrap.dom.appendChild(iframe);
		this.iframe = iframe;

		this.monitorTask = Ext.TaskMgr.start({
			run: this.checkDesignMode,
			scope: this,
			interval:100
		});
	},

	initFrame : function(){
		Ext.TaskMgr.stop(this.monitorTask);
		var doc = this.getDoc();
		this.win = this.getWin();

		doc.open();
		doc.write(this.getDocMarkup());
		doc.close();

		var task = {
			run : function(){
				var doc = this.getDoc();
				if(doc.body || doc.readyState == 'complete'){
					Ext.TaskMgr.stop(task);
					this.setDesignMode(true);
					this.initEditor.defer(10, this);
				}
			},
			interval : 10,
			duration:10000,
			scope: this
		};
		Ext.TaskMgr.start(task);
	},


	checkDesignMode : function(){
		if(this.wrap && this.wrap.dom.offsetWidth){
			var doc = this.getDoc();
			if(!doc){
				return;
			}
			if(!doc.editorInitialized || this.getDesignMode() != 'on'){
				this.initFrame();
			}
		}
	},


	setDesignMode : function(mode){
		var doc = this.getDoc();
		if (doc) {
			if(this.readOnly){
				mode = false;
			}
			doc.designMode = (/on|true/i).test(String(mode).toLowerCase()) ?'on':'off';
		}

	},


	getDesignMode : function(){
		var doc = this.getDoc();
		if(!doc){
			return '';
		}
		return String(doc.designMode).toLowerCase();

	},

	disableItems: function(disabled){
		if(this.fontSelect){
			this.fontSelect.dom.disabled = disabled;
		}
		this.tb.items.each(function(item){
			if(item.getItemId() != 'sourceedit'){
				item.setDisabled(disabled);
			}
		});
	},


	onResize : function(w, h){
		Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);
		if(this.el && this.iframe){
			if(Ext.isNumber(w)){
				var aw = w - this.wrap.getFrameWidth('lr');
				this.el.setWidth(aw);
				this.tb.setWidth(aw);
				this.iframe.style.width = Math.max(aw, 0) + 'px';
			}
			if(Ext.isNumber(h)){
				var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();
				this.el.setHeight(ah);
				this.iframe.style.height = Math.max(ah, 0) + 'px';
				var bd = this.getEditorBody();
				if(bd){
					bd.style.height = Math.max((ah - (this.iframePad*2)), 0) + 'px';
				}
			}
		}
	},


	toggleSourceEdit : function(sourceEditMode){
		var iframeHeight,
		elHeight;

		if (sourceEditMode === undefined) {
			sourceEditMode = !this.sourceEditMode;
		}
		this.sourceEditMode = sourceEditMode === true;
		var btn = this.tb.getComponent('sourceedit');

		if (btn.pressed !== this.sourceEditMode) {
			btn.toggle(this.sourceEditMode);
			if (!btn.xtbHidden) {
				return;
			}
		}
		if (this.sourceEditMode) {

			this.previousSize = this.getSize();

			iframeHeight = Ext.get(this.iframe).getHeight();

			this.disableItems(true);
			this.syncValue();
			this.iframe.className = 'x-hidden';
			this.el.removeClass('x-hidden');
			this.el.dom.removeAttribute('tabIndex');
			this.el.focus();
			this.el.dom.style.height = iframeHeight + 'px';
		}
		else {
			elHeight = parseInt(this.el.dom.style.height, 10);
			if (this.initialized) {
				this.disableItems(this.readOnly);
			}
			this.pushValue();
			this.iframe.className = '';
			this.el.addClass('x-hidden');
			this.el.dom.setAttribute('tabIndex', -1);
			this.deferFocus();

			this.setSize(this.previousSize);
			delete this.previousSize;
			this.iframe.style.height = elHeight + 'px';
		}
		this.fireEvent('editmodechange', this, this.sourceEditMode);
	},


	createLink : function() {
		var url = prompt(this.createLinkText, this.defaultLinkValue);
		if(url && url != 'http:/'+'/'){
			this.relayCmd('createlink', url);
		}
	},


	initEvents : function(){
		this.originalValue = this.getValue();
	},


	markInvalid : Ext.emptyFn,


	clearInvalid : Ext.emptyFn,


	setValue : function(v){
		Ext.form.HtmlEditor.superclass.setValue.call(this, v);
		this.pushValue();
		return this;
	},


	cleanHtml: function(html) {
		html = String(html);
		if(Ext.isWebKit){
			html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
		}


		if(html.charCodeAt(0) == this.defaultValue.replace(/\D/g, '')){
			html = html.substring(1);
		}
		return html;
	},


	syncValue : function(){
		if(this.initialized){
			var bd = this.getEditorBody();
			var html = bd.innerHTML;
			if(Ext.isWebKit){
				var bs = bd.getAttribute('style');
				var m = bs.match(/text-align:(.*?);/i);
				if(m && m[1]){
					html = '<div style="'+m[0]+'">' + html + '</div>';
				}
			}
			html = this.cleanHtml(html);
			if(this.fireEvent('beforesync', this, html) !== false){
				this.el.dom.value = html;
				this.fireEvent('sync', this, html);
			}
		}
	},


	getValue : function() {
		this[this.sourceEditMode ? 'pushValue' : 'syncValue']();
		return Ext.form.HtmlEditor.superclass.getValue.call(this);
	},


	pushValue : function(){
		if(this.initialized){
			var v = this.el.dom.value;
			if(!this.activated && v.length < 1){
				v = this.defaultValue;
			}
			if(this.fireEvent('beforepush', this, v) !== false){
				this.getEditorBody().innerHTML = v;
				if(Ext.isGecko){

					this.setDesignMode(false);
					this.setDesignMode(true);
				}
				this.fireEvent('push', this, v);
			}

		}
	},


	deferFocus : function(){
		this.focus.defer(10, this);
	},


	focus : function(){
		if(this.win && !this.sourceEditMode){
			this.win.focus();
		}else{
			this.el.focus();
		}
	},


	initEditor : function(){

		try{
			var dbody = this.getEditorBody(),
			ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat', 'background-color', 'color'),
			doc,
			fn;

			ss['background-attachment'] = 'fixed';
			dbody.bgProperties = 'fixed';

			Ext.DomHelper.applyStyles(dbody, ss);

			doc = this.getDoc();

			if(doc){
				try{
					Ext.EventManager.removeAll(doc);
				}catch(e){}
			}


			fn = this.onEditorEvent.createDelegate(this);
			Ext.EventManager.on(doc, {
				mousedown: fn,
				dblclick: fn,
				click: fn,
				keyup: fn,
				buffer:100
			});

			if(Ext.isGecko){
				Ext.EventManager.on(doc, 'keypress', this.applyCommand, this);
			}
			if(Ext.isIE || Ext.isWebKit || Ext.isOpera){
				Ext.EventManager.on(doc, 'keydown', this.fixKeys, this);
			}
			doc.editorInitialized = true;
			this.initialized = true;
			this.pushValue();
			this.setReadOnly(this.readOnly);
			this.fireEvent('initialize', this);
		}catch(e){}
	},


	beforeDestroy : function(){
		if(this.monitorTask){
			Ext.TaskMgr.stop(this.monitorTask);
		}
		if(this.rendered){
			Ext.destroy(this.tb);
			var doc = this.getDoc();
			if(doc){
				try{
					Ext.EventManager.removeAll(doc);
					for (var prop in doc){
						delete doc[prop];
					}
				}catch(e){}
			}
			if(this.wrap){
				this.wrap.dom.innerHTML = '';
				this.wrap.remove();
			}
		}
		Ext.form.HtmlEditor.superclass.beforeDestroy.call(this);
	},


	onFirstFocus : function(){
		this.activated = true;
		this.disableItems(this.readOnly);
		if(Ext.isGecko){
			this.win.focus();
			var s = this.win.getSelection();
			if(!s.focusNode || s.focusNode.nodeType != 3){
				var r = s.getRangeAt(0);
				r.selectNodeContents(this.getEditorBody());
				r.collapse(true);
				this.deferFocus();
			}
			try{
				this.execCmd('useCSS', true);
				this.execCmd('styleWithCSS', false);
			}catch(e){}
		}
		this.fireEvent('activate', this);
	},


	adjustFont: function(btn){
		var adjust = btn.getItemId() == 'increasefontsize' ? 1 : -1,
		doc = this.getDoc(),
		v = parseInt(doc.queryCommandValue('FontSize') || 2, 10);
		if((Ext.isSafari && !Ext.isSafari2) || Ext.isChrome || Ext.isAir){


			if(v <= 10){
				v = 1 + adjust;
			}else if(v <= 13){
				v = 2 + adjust;
			}else if(v <= 16){
				v = 3 + adjust;
			}else if(v <= 18){
				v = 4 + adjust;
			}else if(v <= 24){
				v = 5 + adjust;
			}else {
				v = 6 + adjust;
			}
			v = v.constrain(1, 6);
		}else{
			if(Ext.isSafari){
				adjust *= 2;
			}
			v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0);
		}
		this.execCmd('FontSize', v);
	},


	onEditorEvent : function(e){
		this.updateToolbar();
	},



	updateToolbar: function(){

		if(this.readOnly){
			return;
		}

		if(!this.activated){
			this.onFirstFocus();
			return;
		}

		var btns = this.tb.items.map,
		doc = this.getDoc();

		if(this.enableFont && !Ext.isSafari2){
			var name = (doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase();
			if(name != this.fontSelect.dom.value){
				this.fontSelect.dom.value = name;
			}
		}
		if(this.enableFormat){
			btns.bold.toggle(doc.queryCommandState('bold'));
			btns.italic.toggle(doc.queryCommandState('italic'));
			btns.underline.toggle(doc.queryCommandState('underline'));
		}
		if(this.enableAlignments){
			btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));
			btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));
			btns.justifyright.toggle(doc.queryCommandState('justifyright'));
		}
		if(!Ext.isSafari2 && this.enableLists){
			btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));
			btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));
		}

		Ext.menu.MenuMgr.hideAll();

		this.syncValue();
	},


	relayBtnCmd : function(btn){
		this.relayCmd(btn.getItemId());
	},


	relayCmd : function(cmd, value){
		(function(){
			this.focus();
			this.execCmd(cmd, value);
			this.updateToolbar();
		}).defer(10, this);
	},


	execCmd : function(cmd, value){
		var doc = this.getDoc();
		doc.execCommand(cmd, false, value === undefined ? null : value);
		this.syncValue();
	},


	applyCommand : function(e){
		if(e.ctrlKey){
			var c = e.getCharCode(), cmd;
			if(c > 0){
				c = String.fromCharCode(c);
				switch(c){
					case 'b':
						cmd = 'bold';
						break;
					case 'i':
						cmd = 'italic';
						break;
					case 'u':
						cmd = 'underline';
						break;
				}
				if(cmd){
					this.win.focus();
					this.execCmd(cmd);
					this.deferFocus();
					e.preventDefault();
				}
			}
		}
	},


	insertAtCursor : function(text){
		if(!this.activated){
			return;
		}
		if(Ext.isIE){
			this.win.focus();
			var doc = this.getDoc(),
			r = doc.selection.createRange();
			if(r){
				r.pasteHTML(text);
				this.syncValue();
				this.deferFocus();
			}
		}else{
			this.win.focus();
			this.execCmd('InsertHTML', text);
			this.deferFocus();
		}
	},


	fixKeys : function(){
		if(Ext.isIE){
			return function(e){
				var k = e.getKey(),
				doc = this.getDoc(),
				r;
				if(k == e.TAB){
					e.stopEvent();
					r = doc.selection.createRange();
					if(r){
						r.collapse(true);
						r.pasteHTML('&nbsp;&nbsp;&nbsp;&nbsp;');
						this.deferFocus();
					}
				}else if(k == e.ENTER){
					r = doc.selection.createRange();
					if(r){
						var target = r.parentElement();
						if(!target || target.tagName.toLowerCase() != 'li'){
							e.stopEvent();
							r.pasteHTML('<br />');
							r.collapse(false);
							r.select();
						}
					}
				}
			};
		}else if(Ext.isOpera){
			return function(e){
				var k = e.getKey();
				if(k == e.TAB){
					e.stopEvent();
					this.win.focus();
					this.execCmd('InsertHTML','&nbsp;&nbsp;&nbsp;&nbsp;');
					this.deferFocus();
				}
			};
		}else if(Ext.isWebKit){
			return function(e){
				var k = e.getKey();
				if(k == e.TAB){
					e.stopEvent();
					this.execCmd('InsertText','\t');
					this.deferFocus();
				}else if(k == e.ENTER){
					e.stopEvent();
					this.execCmd('InsertHtml','<br /><br />');
					this.deferFocus();
				}
			};
		}
	}(),


	getToolbar : function(){
		return this.tb;
	},


	buttonTips : {
		bold : {
			title: 'Bold (Ctrl+B)',
			text: 'Make the selected text bold.',
			cls: 'x-html-editor-tip'
		},
		italic : {
			title: 'Italic (Ctrl+I)',
			text: 'Make the selected text italic.',
			cls: 'x-html-editor-tip'
		},
		underline : {
			title: 'Underline (Ctrl+U)',
			text: 'Underline the selected text.',
			cls: 'x-html-editor-tip'
		},
		increasefontsize : {
			title: 'Grow Text',
			text: 'Increase the font size.',
			cls: 'x-html-editor-tip'
		},
		decreasefontsize : {
			title: 'Shrink Text',
			text: 'Decrease the font size.',
			cls: 'x-html-editor-tip'
		},
		backcolor : {
			title: 'Text Highlight Color',
			text: 'Change the background color of the selected text.',
			cls: 'x-html-editor-tip'
		},
		forecolor : {
			title: 'Font Color',
			text: 'Change the color of the selected text.',
			cls: 'x-html-editor-tip'
		},
		justifyleft : {
			title: 'Align Text Left',
			text: 'Align text to the left.',
			cls: 'x-html-editor-tip'
		},
		justifycenter : {
			title: 'Center Text',
			text: 'Center text in the editor.',
			cls: 'x-html-editor-tip'
		},
		justifyright : {
			title: 'Align Text Right',
			text: 'Align text to the right.',
			cls: 'x-html-editor-tip'
		},
		insertunorderedlist : {
			title: 'Bullet List',
			text: 'Start a bulleted list.',
			cls: 'x-html-editor-tip'
		},
		insertorderedlist : {
			title: 'Numbered List',
			text: 'Start a numbered list.',
			cls: 'x-html-editor-tip'
		},
		createlink : {
			title: 'Hyperlink',
			text: 'Make the selected text a hyperlink.',
			cls: 'x-html-editor-tip'
		},
		sourceedit : {
			title: 'Source Edit',
			text: 'Switch to source editing mode.',
			cls: 'x-html-editor-tip'
		}
	}



































});
Ext.reg('htmleditor', Ext.form.HtmlEditor);

Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {

	minValue : undefined,

	maxValue : undefined,

	minText : "The time in this field must be equal to or after {0}",

	maxText : "The time in this field must be equal to or before {0}",

	invalidText : "{0} is not a valid time",

	format : "g:i A",

	altFormats : "g:ia|g:iA|g:i a|g:i A|h:i|g:i|H:i|ga|ha|gA|h a|g a|g A|gi|hi|gia|hia|g|H|gi a|hi a|giA|hiA|gi A|hi A",

	increment: 15,


	mode: 'local',

	triggerAction: 'all',

	typeAhead: false,




	initDate: '1/1/2008',

	initDateFormat: 'j/n/Y',


	initComponent : function(){
		if(Ext.isDefined(this.minValue)){
			this.setMinValue(this.minValue, true);
		}
		if(Ext.isDefined(this.maxValue)){
			this.setMaxValue(this.maxValue, true);
		}
		if(!this.store){
			this.generateStore(true);
		}
		Ext.form.TimeField.superclass.initComponent.call(this);
	},


	setMinValue: function(value,  initial){
		this.setLimit(value, true, initial);
		return this;
	},


	setMaxValue: function(value,  initial){
		this.setLimit(value, false, initial);
		return this;
	},


	generateStore: function(initial){
		var min = this.minValue || new Date(this.initDate).clearTime(),
		max = this.maxValue || new Date(this.initDate).clearTime().add('mi', (24 * 60) - 1),
		times = [];

		while(min <= max){
			times.push(min.dateFormat(this.format));
			min = min.add('mi', this.increment);
		}
		this.bindStore(times, initial);
	},


	setLimit: function(value, isMin, initial){
		var d;
		if(Ext.isString(value)){
			d = this.parseDate(value);
		}else if(Ext.isDate(value)){
			d = value;
		}
		if(d){
			var val = new Date(this.initDate).clearTime();
			val.setHours(d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
			this[isMin ? 'minValue' : 'maxValue'] = val;
			if(!initial){
				this.generateStore();
			}
		}
	},


	getValue : function(){
		var v = Ext.form.TimeField.superclass.getValue.call(this);
		return this.formatDate(this.parseDate(v)) || '';
	},


	setValue : function(value){
		return Ext.form.TimeField.superclass.setValue.call(this, this.formatDate(this.parseDate(value)));
	},


	validateValue : Ext.form.DateField.prototype.validateValue,

	formatDate : Ext.form.DateField.prototype.formatDate,

	parseDate: function(value) {
		if (!value || Ext.isDate(value)) {
			return value;
		}

		var id = this.initDate + ' ',
		idf = this.initDateFormat + ' ',
		v = Date.parseDate(id + value, idf + this.format),
		af = this.altFormats;

		if (!v && af) {
			if (!this.altFormatsArray) {
				this.altFormatsArray = af.split("|");
			}
			for (var i = 0, afa = this.altFormatsArray, len = afa.length; i < len && !v; i++) {
				v = Date.parseDate(id + value, idf + afa[i]);
			}
		}

		return v;
	}
});
Ext.reg('timefield', Ext.form.TimeField);
Ext.form.SliderField = Ext.extend(Ext.form.Field, {


	useTips : true,


	tipText : null,


	actionMode: 'wrap',


	initComponent : function() {
		var cfg = Ext.copyTo({
			id: this.id + '-slider'
		}, this.initialConfig, ['vertical', 'minValue', 'maxValue', 'decimalPrecision', 'keyIncrement', 'increment', 'clickToChange', 'animate']);


		if (this.useTips) {
			var plug = this.tipText ? {
				getText: this.tipText
				} : {};
			cfg.plugins = [new Ext.slider.Tip(plug)];
		}
		this.slider = new Ext.Slider(cfg);
		Ext.form.SliderField.superclass.initComponent.call(this);
	},


	onRender : function(ct, position){
		this.autoCreate = {
			id: this.id,
			name: this.name,
			type: 'hidden',
			tag: 'input'
		};
		Ext.form.SliderField.superclass.onRender.call(this, ct, position);
		this.wrap = this.el.wrap({
			cls: 'x-form-field-wrap'
		});
		this.resizeEl = this.positionEl = this.wrap;
		this.slider.render(this.wrap);
	},


	onResize : function(w, h, aw, ah){
		Ext.form.SliderField.superclass.onResize.call(this, w, h, aw, ah);
		this.slider.setSize(w, h);
	},


	initEvents : function(){
		Ext.form.SliderField.superclass.initEvents.call(this);
		this.slider.on('change', this.onChange, this);
	},


	onChange : function(slider, v){
		this.setValue(v, undefined, true);
	},


	onEnable : function(){
		Ext.form.SliderField.superclass.onEnable.call(this);
		this.slider.enable();
	},


	onDisable : function(){
		Ext.form.SliderField.superclass.onDisable.call(this);
		this.slider.disable();
	},


	beforeDestroy : function(){
		Ext.destroy(this.slider);
		Ext.form.SliderField.superclass.beforeDestroy.call(this);
	},


	alignErrorIcon : function(){
		this.errorIcon.alignTo(this.slider.el, 'tl-tr', [2, 0]);
	},


	setMinValue : function(v){
		this.slider.setMinValue(v);
		return this;
	},


	setMaxValue : function(v){
		this.slider.setMaxValue(v);
		return this;
	},


	setValue : function(v, animate,  silent){


		if(!silent){
			this.slider.setValue(v, animate);
		}
		return Ext.form.SliderField.superclass.setValue.call(this, this.slider.getValue());
	},


	getValue : function(){
		return this.slider.getValue();
	}
});

Ext.reg('sliderfield', Ext.form.SliderField);
Ext.form.Label = Ext.extend(Ext.BoxComponent, {





	onRender : function(ct, position){
		if(!this.el){
			this.el = document.createElement('label');
			this.el.id = this.getId();
			this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || '');
			if(this.forId){
				this.el.setAttribute('for', this.forId);
			}
		}
		Ext.form.Label.superclass.onRender.call(this, ct, position);
	},


	setText : function(t, encode){
		var e = encode === false;
		this[!e ? 'text' : 'html'] = t;
		delete this[e ? 'text' : 'html'];
		if(this.rendered){
			this.el.dom.innerHTML = encode !== false ? Ext.util.Format.htmlEncode(t) : t;
		}
		return this;
	}
});

Ext.reg('label', Ext.form.Label);
Ext.form.Action = function(form, options){
	this.form = form;
	this.options = options || {};
};


Ext.form.Action.CLIENT_INVALID = 'client';

Ext.form.Action.SERVER_INVALID = 'server';

Ext.form.Action.CONNECT_FAILURE = 'connect';

Ext.form.Action.LOAD_FAILURE = 'load';

Ext.form.Action.prototype = {














	type : 'default',





	run : function(options){

	},


	success : function(response){

	},


	handleResponse : function(response){

	},


	failure : function(response){
		this.response = response;
		this.failureType = Ext.form.Action.CONNECT_FAILURE;
		this.form.afterAction(this, false);
	},




	processResponse : function(response){
		this.response = response;
		if(!response.responseText && !response.responseXML){
			return true;
		}
		this.result = this.handleResponse(response);
		return this.result;
	},


	getUrl : function(appendParams){
		var url = this.options.url || this.form.url || this.form.el.dom.action;
		if(appendParams){
			var p = this.getParams();
			if(p){
				url = Ext.urlAppend(url, p);
			}
		}
		return url;
	},


	getMethod : function(){
		return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
	},


	getParams : function(){
		var bp = this.form.baseParams;
		var p = this.options.params;
		if(p){
			if(typeof p == "object"){
				p = Ext.urlEncode(Ext.applyIf(p, bp));
			}else if(typeof p == 'string' && bp){
				p += '&' + Ext.urlEncode(bp);
			}
		}else if(bp){
			p = Ext.urlEncode(bp);
		}
		return p;
	},


	createCallback : function(opts){
		var opts = opts || {};
		return {
			success: this.success,
			failure: this.failure,
			scope: this,
			timeout: (opts.timeout*1000) || (this.form.timeout*1000),
			upload: this.form.fileUpload ? this.success : undefined
		};
	}
};


Ext.form.Action.Submit = function(form, options){
	Ext.form.Action.Submit.superclass.constructor.call(this, form, options);
};

Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {


	type : 'submit',


	run : function(){
		var o = this.options,
		method = this.getMethod(),
		isGet = method == 'GET';
		if(o.clientValidation === false || this.form.isValid()){
			if (o.submitEmptyText === false) {
				var fields = this.form.items,
				emptyFields = [],
				setupEmptyFields = function(f){
					if (f.el.getValue() == f.emptyText) {
						emptyFields.push(f);
						f.el.dom.value = "";
					}
					if(f.isComposite && f.rendered){
						f.items.each(setupEmptyFields);
					}
				};

				fields.each(setupEmptyFields);
			}
			Ext.Ajax.request(Ext.apply(this.createCallback(o), {
				form:this.form.el.dom,
				url:this.getUrl(isGet),
				method: method,
				headers: o.headers,
				params:!isGet ? this.getParams() : null,
				isUpload: this.form.fileUpload
			}));
			if (o.submitEmptyText === false) {
				Ext.each(emptyFields, function(f) {
					if (f.applyEmptyText) {
						f.applyEmptyText();
					}
				});
			}
		}else if (o.clientValidation !== false){
			this.failureType = Ext.form.Action.CLIENT_INVALID;
			this.form.afterAction(this, false);
		}
	},


	success : function(response){
		var result = this.processResponse(response);
		if(result === true || result.success){
			this.form.afterAction(this, true);
			return;
		}
		if(result.errors){
			this.form.markInvalid(result.errors);
		}
		this.failureType = Ext.form.Action.SERVER_INVALID;
		this.form.afterAction(this, false);
	},


	handleResponse : function(response){
		if(this.form.errorReader){
			var rs = this.form.errorReader.read(response);
			var errors = [];
			if(rs.records){
				for(var i = 0, len = rs.records.length; i < len; i++) {
					var r = rs.records[i];
					errors[i] = r.data;
				}
			}
			if(errors.length < 1){
				errors = null;
			}
			return {
				success : rs.success,
				errors : errors
			};
		}
		return Ext.decode(response.responseText);
	}
});



Ext.form.Action.Load = function(form, options){
	Ext.form.Action.Load.superclass.constructor.call(this, form, options);
	this.reader = this.form.reader;
};

Ext.extend(Ext.form.Action.Load, Ext.form.Action, {

	type : 'load',


	run : function(){
		Ext.Ajax.request(Ext.apply(
			this.createCallback(this.options), {
				method:this.getMethod(),
				url:this.getUrl(false),
				headers: this.options.headers,
				params:this.getParams()
			}));
	},


	success : function(response){
		var result = this.processResponse(response);
		if(result === true || !result.success || !result.data){
			this.failureType = Ext.form.Action.LOAD_FAILURE;
			this.form.afterAction(this, false);
			return;
		}
		this.form.clearInvalid();
		this.form.setValues(result.data);
		this.form.afterAction(this, true);
	},


	handleResponse : function(response){
		if(this.form.reader){
			var rs = this.form.reader.read(response);
			var data = rs.records && rs.records[0] ? rs.records[0].data : null;
			return {
				success : rs.success,
				data : data
			};
		}
		return Ext.decode(response.responseText);
	}
});




Ext.form.Action.DirectLoad = Ext.extend(Ext.form.Action.Load, {
	constructor: function(form, opts) {
		Ext.form.Action.DirectLoad.superclass.constructor.call(this, form, opts);
	},
	type : 'directload',

	run : function(){
		var args = this.getParams();
		args.push(this.success, this);
		this.form.api.load.apply(window, args);
	},

	getParams : function() {
		var buf = [], o = {};
		var bp = this.form.baseParams;
		var p = this.options.params;
		Ext.apply(o, p, bp);
		var paramOrder = this.form.paramOrder;
		if(paramOrder){
			for(var i = 0, len = paramOrder.length; i < len; i++){
				buf.push(o[paramOrder[i]]);
			}
		}else if(this.form.paramsAsHash){
			buf.push(o);
		}
		return buf;
	},



	processResponse : function(result) {
		this.result = result;
		return result;
	},

	success : function(response, trans){
		if(trans.type == Ext.Direct.exceptions.SERVER){
			response = {};
		}
		Ext.form.Action.DirectLoad.superclass.success.call(this, response);
	}
});


Ext.form.Action.DirectSubmit = Ext.extend(Ext.form.Action.Submit, {
	constructor : function(form, opts) {
		Ext.form.Action.DirectSubmit.superclass.constructor.call(this, form, opts);
	},
	type : 'directsubmit',

	run : function(){
		var o = this.options;
		if(o.clientValidation === false || this.form.isValid()){


			this.success.params = this.getParams();
			this.form.api.submit(this.form.el.dom, this.success, this);
		}else if (o.clientValidation !== false){
			this.failureType = Ext.form.Action.CLIENT_INVALID;
			this.form.afterAction(this, false);
		}
	},

	getParams : function() {
		var o = {};
		var bp = this.form.baseParams;
		var p = this.options.params;
		Ext.apply(o, p, bp);
		return o;
	},



	processResponse : function(result) {
		this.result = result;
		return result;
	},

	success : function(response, trans){
		if(trans.type == Ext.Direct.exceptions.SERVER){
			response = {};
		}
		Ext.form.Action.DirectSubmit.superclass.success.call(this, response);
	}
});

Ext.form.Action.ACTION_TYPES = {
	'load' : Ext.form.Action.Load,
	'submit' : Ext.form.Action.Submit,
	'directload' : Ext.form.Action.DirectLoad,
	'directsubmit' : Ext.form.Action.DirectSubmit
};

Ext.form.VTypes = function(){

	var alpha = /^[a-zA-Z_]+$/,
	alphanum = /^[a-zA-Z0-9_]+$/,
	email = /^(\w+)([\-+.][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}$/,
	url = /(((^https?)|(^ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;


	return {

		'email' : function(v){
			return email.test(v);
		},

		'emailText' : 'This field should be an e-mail address in the format "user@example.com"',

		'emailMask' : /[a-z0-9_\.\-@\+]/i,


		'url' : function(v){
			return url.test(v);
		},

		'urlText' : 'This field should be a URL in the format "http:/'+'/www.example.com"',


		'alpha' : function(v){
			return alpha.test(v);
		},

		'alphaText' : 'This field should only contain letters and _',

		'alphaMask' : /[a-z_]/i,


		'alphanum' : function(v){
			return alphanum.test(v);
		},

		'alphanumText' : 'This field should only contain letters, numbers and _',

		'alphanumMask' : /[a-z0-9_]/i
	};
}();

Ext.grid.GridPanel = Ext.extend(Ext.Panel, {

	autoExpandColumn : false,


	autoExpandMax : 1000,


	autoExpandMin : 50,


	columnLines : false,






	ddText : '{0} selected row{1}',


	deferRowRender : true,




	enableColumnHide : true,


	enableColumnMove : true,


	enableDragDrop : false,


	enableHdMenu : true,



	loadMask : false,



	minColumnWidth : 25,





	stripeRows : false,


	trackMouseOver : true,


	stateEvents : ['columnmove', 'columnresize', 'sortchange', 'groupchange'],


	view : null,


	bubbleEvents: [],




	rendered : false,


	viewReady : false,


	initComponent : function() {
		Ext.grid.GridPanel.superclass.initComponent.call(this);

		if (this.columnLines) {
			this.cls = (this.cls || '') + ' x-grid-with-col-lines';
		}


		this.autoScroll = false;
		this.autoWidth = false;

		if(Ext.isArray(this.columns)){
			this.colModel = new Ext.grid.ColumnModel(this.columns);
			delete this.columns;
		}


		if(this.ds){
			this.store = this.ds;
			delete this.ds;
		}
		if(this.cm){
			this.colModel = this.cm;
			delete this.cm;
		}
		if(this.sm){
			this.selModel = this.sm;
			delete this.sm;
		}
		this.store = Ext.StoreMgr.lookup(this.store);

		this.addEvents(


			'click',

			'dblclick',

			'contextmenu',

			'mousedown',

			'mouseup',

			'mouseover',

			'mouseout',

			'keypress',

			'keydown',



			'cellmousedown',

			'rowmousedown',

			'headermousedown',


			'groupmousedown',


			'rowbodymousedown',


			'containermousedown',


			'cellclick',

			'celldblclick',

			'rowclick',

			'rowdblclick',

			'headerclick',

			'headerdblclick',

			'groupclick',

			'groupdblclick',

			'containerclick',

			'containerdblclick',


			'rowbodyclick',

			'rowbodydblclick',


			'rowcontextmenu',

			'cellcontextmenu',

			'headercontextmenu',

			'groupcontextmenu',

			'containercontextmenu',

			'rowbodycontextmenu',

			'bodyscroll',

			'columnresize',

			'columnmove',

			'sortchange',

			'groupchange',

			'reconfigure',

			'viewready'
			);
	},


	onRender : function(ct, position){
		Ext.grid.GridPanel.superclass.onRender.apply(this, arguments);

		var c = this.getGridEl();

		this.el.addClass('x-grid-panel');

		this.mon(c, {
			scope: this,
			mousedown: this.onMouseDown,
			click: this.onClick,
			dblclick: this.onDblClick,
			contextmenu: this.onContextMenu
		});

		this.relayEvents(c, ['mousedown','mouseup','mouseover','mouseout','keypress', 'keydown']);

		var view = this.getView();
		view.init(this);
		view.render();
		this.getSelectionModel().init(this);
	},


	initEvents : function(){
		Ext.grid.GridPanel.superclass.initEvents.call(this);

		if(this.loadMask){
			this.loadMask = new Ext.LoadMask(this.bwrap,
				Ext.apply({
					store:this.store
					}, this.loadMask));
		}
	},

	initStateEvents : function(){
		Ext.grid.GridPanel.superclass.initStateEvents.call(this);
		this.mon(this.colModel, 'hiddenchange', this.saveState, this, {
			delay: 100
		});
	},

	applyState : function(state){
		var cm = this.colModel,
		cs = state.columns,
		store = this.store,
		s,
		c,
		colIndex;

		if(cs){
			for(var i = 0, len = cs.length; i < len; i++){
				s = cs[i];
				c = cm.getColumnById(s.id);
				if(c){
					colIndex = cm.getIndexById(s.id);
					cm.setState(colIndex, {
						hidden: s.hidden,
						width: s.width,
						sortable: s.sortable
					});
					if(colIndex != i){
						cm.moveColumn(colIndex, i);
					}
				}
			}
		}
		if(store){
			s = state.sort;
			if(s){
				store[store.remoteSort ? 'setDefaultSort' : 'sort'](s.field, s.direction);
			}
			s = state.group;
			if(store.groupBy){
				if(s){
					store.groupBy(s);
				}else{
					store.clearGrouping();
				}
			}

		}
		var o = Ext.apply({}, state);
		delete o.columns;
		delete o.sort;
		Ext.grid.GridPanel.superclass.applyState.call(this, o);
	},

	getState : function(){
		var o = {
			columns: []
		},
		store = this.store,
		ss,
		gs;

		for(var i = 0, c; (c = this.colModel.config[i]); i++){
			o.columns[i] = {
				id: c.id,
				width: c.width
			};
			if(c.hidden){
				o.columns[i].hidden = true;
			}
			if(c.sortable){
				o.columns[i].sortable = true;
			}
		}
		if(store){
			ss = store.getSortState();
			if(ss){
				o.sort = ss;
			}
			if(store.getGroupState){
				gs = store.getGroupState();
				if(gs){
					o.group = gs;
				}
			}
		}
		return o;
	},


	afterRender : function(){
		Ext.grid.GridPanel.superclass.afterRender.call(this);
		var v = this.view;
		this.on('bodyresize', v.layout, v);
		v.layout(true);
		if(this.deferRowRender){
			if (!this.deferRowRenderTask){
				this.deferRowRenderTask = new Ext.util.DelayedTask(v.afterRender, this.view);
			}
			this.deferRowRenderTask.delay(10);
		}else{
			v.afterRender();
		}
		this.viewReady = true;
	},


	reconfigure : function(store, colModel){
		var rendered = this.rendered;
		if(rendered){
			if(this.loadMask){
				this.loadMask.destroy();
				this.loadMask = new Ext.LoadMask(this.bwrap,
					Ext.apply({}, {
						store:store
					}, this.initialConfig.loadMask));
			}
		}
		if(this.view){
			this.view.initData(store, colModel);
		}
		this.store = store;
		this.colModel = colModel;
		if(rendered){
			this.view.refresh(true);
		}
		this.fireEvent('reconfigure', this, store, colModel);
	},


	onDestroy : function(){
		if (this.deferRowRenderTask && this.deferRowRenderTask.cancel){
			this.deferRowRenderTask.cancel();
		}
		if(this.rendered){
			Ext.destroy(this.view, this.loadMask);
		}else if(this.store && this.store.autoDestroy){
			this.store.destroy();
		}
		Ext.destroy(this.colModel, this.selModel);
		this.store = this.selModel = this.colModel = this.view = this.loadMask = null;
		Ext.grid.GridPanel.superclass.onDestroy.call(this);
	},


	processEvent : function(name, e){
		this.view.processEvent(name, e);
	},


	onClick : function(e){
		this.processEvent('click', e);
	},


	onMouseDown : function(e){
		this.processEvent('mousedown', e);
	},


	onContextMenu : function(e, t){
		this.processEvent('contextmenu', e);
	},


	onDblClick : function(e){
		this.processEvent('dblclick', e);
	},


	walkCells : function(row, col, step, fn, scope){
		var cm    = this.colModel,
		clen  = cm.getColumnCount(),
		ds    = this.store,
		rlen  = ds.getCount(),
		first = true;

		if(step < 0){
			if(col < 0){
				row--;
				first = false;
			}
			while(row >= 0){
				if(!first){
					col = clen-1;
				}
				first = false;
				while(col >= 0){
					if(fn.call(scope || this, row, col, cm) === true){
						return [row, col];
					}
					col--;
				}
				row--;
			}
		} else {
			if(col >= clen){
				row++;
				first = false;
			}
			while(row < rlen){
				if(!first){
					col = 0;
				}
				first = false;
				while(col < clen){
					if(fn.call(scope || this, row, col, cm) === true){
						return [row, col];
					}
					col++;
				}
				row++;
			}
		}
		return null;
	},


	getGridEl : function(){
		return this.body;
	},


	stopEditing : Ext.emptyFn,


	getSelectionModel : function(){
		if(!this.selModel){
			this.selModel = new Ext.grid.RowSelectionModel(
				this.disableSelection ? {
					selectRow: Ext.emptyFn
					} : null);
		}
		return this.selModel;
	},


	getStore : function(){
		return this.store;
	},


	getColumnModel : function(){
		return this.colModel;
	},


	getView : function() {
		if (!this.view) {
			this.view = new Ext.grid.GridView(this.viewConfig);
		}

		return this.view;
	},

	getDragDropText : function(){
		var count = this.selModel.getCount();
		return String.format(this.ddText, count, count == 1 ? '' : 's');
	}



















































});
Ext.reg('grid', Ext.grid.GridPanel);
Ext.grid.PivotGrid = Ext.extend(Ext.grid.GridPanel, {


	aggregator: 'sum',


	renderer: undefined,








	initComponent: function() {
		Ext.grid.PivotGrid.superclass.initComponent.apply(this, arguments);

		this.initAxes();


		this.enableColumnResize = false;

		this.viewConfig = Ext.apply(this.viewConfig || {}, {
			forceFit: true
		});



		this.colModel = new Ext.grid.ColumnModel({});
	},


	getAggregator: function() {
		if (typeof this.aggregator == 'string') {
			return Ext.grid.PivotAggregatorMgr.types[this.aggregator];
		} else {
			return this.aggregator;
		}
	},


	setAggregator: function(aggregator) {
		this.aggregator = aggregator;
	},


	setMeasure: function(measure) {
		this.measure = measure;
	},


	setLeftAxis: function(axis, refresh) {

		this.leftAxis = axis;

		if (refresh) {
			this.view.refresh();
		}
	},


	setTopAxis: function(axis, refresh) {

		this.topAxis = axis;

		if (refresh) {
			this.view.refresh();
		}
	},


	initAxes: function() {
		var PivotAxis = Ext.grid.PivotAxis;

		if (!(this.leftAxis instanceof PivotAxis)) {
			this.setLeftAxis(new PivotAxis({
				orientation: 'vertical',
				dimensions : this.leftAxis || [],
				store      : this.store
			}));
		};

		if (!(this.topAxis instanceof PivotAxis)) {
			this.setTopAxis(new PivotAxis({
				orientation: 'horizontal',
				dimensions : this.topAxis || [],
				store      : this.store
			}));
		};
	},


	extractData: function() {
		var records  = this.store.data.items,
		recCount = records.length,
		cells    = [],
		record, i, j, k;

		if (recCount == 0) {
			return [];
		}

		var leftTuples = this.leftAxis.getTuples(),
		leftCount  = leftTuples.length,
		topTuples  = this.topAxis.getTuples(),
		topCount   = topTuples.length,
		aggregator = this.getAggregator();

		for (i = 0; i < recCount; i++) {
			record = records[i];

			for (j = 0; j < leftCount; j++) {
				cells[j] = cells[j] || [];

				if (leftTuples[j].matcher(record) === true) {
					for (k = 0; k < topCount; k++) {
						cells[j][k] = cells[j][k] || [];

						if (topTuples[k].matcher(record)) {
							cells[j][k].push(record);
						}
					}
				}
			}
		}

		var rowCount = cells.length,
		colCount, row;

		for (i = 0; i < rowCount; i++) {
			row = cells[i];
			colCount = row.length;

			for (j = 0; j < colCount; j++) {
				cells[i][j] = aggregator(cells[i][j], this.measure);
			}
		}

		return cells;
	},


	getView: function() {
		if (!this.view) {
			this.view = new Ext.grid.PivotGridView(this.viewConfig);
		}

		return this.view;
	}
});

Ext.reg('pivotgrid', Ext.grid.PivotGrid);


Ext.grid.PivotAggregatorMgr = new Ext.AbstractManager();

Ext.grid.PivotAggregatorMgr.registerType('sum', function(records, measure) {
	var length = records.length,
	total  = 0,
	i;

	for (i = 0; i < length; i++) {
		total += records[i].get(measure);
	}

	return total;
});

Ext.grid.PivotAggregatorMgr.registerType('avg', function(records, measure) {
	var length = records.length,
	total  = 0,
	i;

	for (i = 0; i < length; i++) {
		total += records[i].get(measure);
	}

	return (total / length) || 'n/a';
});

Ext.grid.PivotAggregatorMgr.registerType('min', function(records, measure) {
	var data   = [],
	length = records.length,
	i;

	for (i = 0; i < length; i++) {
		data.push(records[i].get(measure));
	}

	return Math.min.apply(this, data) || 'n/a';
});

Ext.grid.PivotAggregatorMgr.registerType('max', function(records, measure) {
	var data   = [],
	length = records.length,
	i;

	for (i = 0; i < length; i++) {
		data.push(records[i].get(measure));
	}

	return Math.max.apply(this, data) || 'n/a';
});

Ext.grid.PivotAggregatorMgr.registerType('count', function(records, measure) {
	return records.length;
});
Ext.grid.GridView = Ext.extend(Ext.util.Observable, {











	deferEmptyText : true,


	scrollOffset : undefined,


	autoFill : false,


	forceFit : false,


	sortClasses : ['sort-asc', 'sort-desc'],


	sortAscText : 'Sort Ascending',


	sortDescText : 'Sort Descending',


	columnsText : 'Columns',


	selectedRowClass : 'x-grid3-row-selected',


	borderWidth : 2,
	tdClass : 'x-grid3-cell',
	hdCls : 'x-grid3-hd',



	markDirty : true,


	cellSelectorDepth : 4,


	rowSelectorDepth : 10,


	rowBodySelectorDepth : 10,


	cellSelector : 'td.x-grid3-cell',


	rowSelector : 'div.x-grid3-row',


	rowBodySelector : 'div.x-grid3-row-body',


	firstRowCls: 'x-grid3-row-first',
	lastRowCls: 'x-grid3-row-last',
	rowClsRe: /(?:^|\s+)x-grid3-row-(first|last|alt)(?:\s+|$)/g,


	headerMenuOpenCls: 'x-grid3-hd-menu-open',


	rowOverCls: 'x-grid3-row-over',

	constructor : function(config) {
		Ext.apply(this, config);


		this.addEvents(

			'beforerowremoved',


			'beforerowsinserted',


			'beforerefresh',


			'rowremoved',


			'rowsinserted',


			'rowupdated',


			'refresh'
			);

		Ext.grid.GridView.superclass.constructor.call(this);
	},




	masterTpl: new Ext.Template(
		'<div class="x-grid3" hidefocus="true">',
		'<div class="x-grid3-viewport">',
		'<div class="x-grid3-header">',
		'<div class="x-grid3-header-inner">',
		'<div class="x-grid3-header-offset" style="{ostyle}">{header}</div>',
		'</div>',
		'<div class="x-clear"></div>',
		'</div>',
		'<div class="x-grid3-scroller">',
		'<div class="x-grid3-body" style="{bstyle}">{body}</div>',
		'<a href="#" class="x-grid3-focus" tabIndex="-1"></a>',
		'</div>',
		'</div>',
		'<div class="x-grid3-resize-marker">&#160;</div>',
		'<div class="x-grid3-resize-proxy">&#160;</div>',
		'</div>'
		),


	headerTpl: new Ext.Template(
		'<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
		'<thead>',
		'<tr class="x-grid3-hd-row">{cells}</tr>',
		'</thead>',
		'</table>'
		),


	bodyTpl: new Ext.Template('{rows}'),


	cellTpl: new Ext.Template(
		'<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
		'<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
		'</td>'
		),


	initTemplates : function() {
		var templates = this.templates || {},
		template, name,

		headerCellTpl = new Ext.Template(
			'<td class="x-grid3-hd x-grid3-cell x-grid3-td-{id} {css}" style="{style}">',
			'<div {tooltip} {attr} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">',
			this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '',
			'{value}',
			'<img alt="" class="x-grid3-sort-icon" src="', Ext.BLANK_IMAGE_URL, '" />',
			'</div>',
			'</td>'
			),

		rowBodyText = [
		'<tr class="x-grid3-row-body-tr" style="{bodyStyle}">',
		'<td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on">',
		'<div class="x-grid3-row-body">{body}</div>',
		'</td>',
		'</tr>'
		].join(""),

		innerText = [
		'<table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
		'<tbody>',
		'<tr>{cells}</tr>',
		this.enableRowBody ? rowBodyText : '',
		'</tbody>',
		'</table>'
		].join("");

		Ext.applyIf(templates, {
			hcell   : headerCellTpl,
			cell    : this.cellTpl,
			body    : this.bodyTpl,
			header  : this.headerTpl,
			master  : this.masterTpl,
			row     : new Ext.Template('<div class="x-grid3-row {alt}" style="{tstyle}">' + innerText + '</div>'),
			rowInner: new Ext.Template(innerText)
		});

		for (name in templates) {
			template = templates[name];

			if (template && Ext.isFunction(template.compile) && !template.compiled) {
				template.disableFormats = true;
				template.compile();
			}
		}

		this.templates = templates;
		this.colRe = new RegExp('x-grid3-td-([^\\s]+)', '');
	},


	fly : function(el) {
		if (!this._flyweight) {
			this._flyweight = new Ext.Element.Flyweight(document.body);
		}
		this._flyweight.dom = el;
		return this._flyweight;
	},


	getEditorParent : function() {
		return this.scroller.dom;
	},


	initElements : function() {
		var Element  = Ext.Element,
		el       = Ext.get(this.grid.getGridEl().dom.firstChild),
		mainWrap = new Element(el.child('div.x-grid3-viewport')),
		mainHd   = new Element(mainWrap.child('div.x-grid3-header')),
		scroller = new Element(mainWrap.child('div.x-grid3-scroller'));

		if (this.grid.hideHeaders) {
			mainHd.setDisplayed(false);
		}

		if (this.forceFit) {
			scroller.setStyle('overflow-x', 'hidden');
		}



		Ext.apply(this, {
			el      : el,
			mainWrap: mainWrap,
			scroller: scroller,
			mainHd  : mainHd,
			innerHd : mainHd.child('div.x-grid3-header-inner').dom,
			mainBody: new Element(Element.fly(scroller).child('div.x-grid3-body')),
			focusEl : new Element(Element.fly(scroller).child('a')),

			resizeMarker: new Element(el.child('div.x-grid3-resize-marker')),
			resizeProxy : new Element(el.child('div.x-grid3-resize-proxy'))
		});

		this.focusEl.swallowEvent('click', true);
	},


	getRows : function() {
		return this.hasRows() ? this.mainBody.dom.childNodes : [];
	},




	findCell : function(el) {
		if (!el) {
			return false;
		}
		return this.fly(el).findParent(this.cellSelector, this.cellSelectorDepth);
	},


	findCellIndex : function(el, requiredCls) {
		var cell = this.findCell(el),
		hasCls;

		if (cell) {
			hasCls = this.fly(cell).hasClass(requiredCls);
			if (!requiredCls || hasCls) {
				return this.getCellIndex(cell);
			}
		}
		return false;
	},


	getCellIndex : function(el) {
		if (el) {
			var match = el.className.match(this.colRe);

			if (match && match[1]) {
				return this.cm.getIndexById(match[1]);
			}
		}
		return false;
	},


	findHeaderCell : function(el) {
		var cell = this.findCell(el);
		return cell && this.fly(cell).hasClass(this.hdCls) ? cell : null;
	},


	findHeaderIndex : function(el){
		return this.findCellIndex(el, this.hdCls);
	},


	findRow : function(el) {
		if (!el) {
			return false;
		}
		return this.fly(el).findParent(this.rowSelector, this.rowSelectorDepth);
	},


	findRowIndex : function(el) {
		var row = this.findRow(el);
		return row ? row.rowIndex : false;
	},


	findRowBody : function(el) {
		if (!el) {
			return false;
		}

		return this.fly(el).findParent(this.rowBodySelector, this.rowBodySelectorDepth);
	},




	getRow : function(row) {
		return this.getRows()[row];
	},


	getCell : function(row, col) {
		return Ext.fly(this.getRow(row)).query(this.cellSelector)[col];
	},


	getHeaderCell : function(index) {
		return this.mainHd.dom.getElementsByTagName('td')[index];
	},




	addRowClass : function(rowId, cls) {
		var row = this.getRow(rowId);
		if (row) {
			this.fly(row).addClass(cls);
		}
	},


	removeRowClass : function(row, cls) {
		var r = this.getRow(row);
		if(r){
			this.fly(r).removeClass(cls);
		}
	},


	removeRow : function(row) {
		Ext.removeNode(this.getRow(row));
		this.syncFocusEl(row);
	},


	removeRows : function(firstRow, lastRow) {
		var bd = this.mainBody.dom,
		rowIndex;

		for (rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
			Ext.removeNode(bd.childNodes[firstRow]);
		}

		this.syncFocusEl(firstRow);
	},




	getScrollState : function() {
		var sb = this.scroller.dom;

		return {
			left: sb.scrollLeft,
			top : sb.scrollTop
		};
	},


	restoreScroll : function(state) {
		var sb = this.scroller.dom;
		sb.scrollLeft = state.left;
		sb.scrollTop  = state.top;
	},


	scrollToTop : function() {
		var dom = this.scroller.dom;

		dom.scrollTop  = 0;
		dom.scrollLeft = 0;
	},


	syncScroll : function() {
		this.syncHeaderScroll();
		var mb = this.scroller.dom;
		this.grid.fireEvent('bodyscroll', mb.scrollLeft, mb.scrollTop);
	},


	syncHeaderScroll : function() {
		var innerHd    = this.innerHd,
		scrollLeft = this.scroller.dom.scrollLeft;

		innerHd.scrollLeft = scrollLeft;
		innerHd.scrollLeft = scrollLeft;
	},


	updateSortIcon : function(col, dir) {
		var sortClasses = this.sortClasses,
		sortClass   = sortClasses[dir == "DESC" ? 1 : 0],
		headers     = this.mainHd.select('td').removeClass(sortClasses);

		headers.item(col).addClass(sortClass);
	},


	updateAllColumnWidths : function() {
		var totalWidth = this.getTotalWidth(),
		colCount   = this.cm.getColumnCount(),
		rows       = this.getRows(),
		rowCount   = rows.length,
		widths     = [],
		row, rowFirstChild, trow, i, j;

		for (i = 0; i < colCount; i++) {
			widths[i] = this.getColumnWidth(i);
			this.getHeaderCell(i).style.width = widths[i];
		}

		this.updateHeaderWidth();

		for (i = 0; i < rowCount; i++) {
			row = rows[i];
			row.style.width = totalWidth;
			rowFirstChild = row.firstChild;

			if (rowFirstChild) {
				rowFirstChild.style.width = totalWidth;
				trow = rowFirstChild.rows[0];

				for (j = 0; j < colCount; j++) {
					trow.childNodes[j].style.width = widths[j];
				}
			}
		}

		this.onAllColumnWidthsUpdated(widths, totalWidth);
	},


	updateColumnWidth : function(column, width) {
		var columnWidth = this.getColumnWidth(column),
		totalWidth  = this.getTotalWidth(),
		headerCell  = this.getHeaderCell(column),
		nodes       = this.getRows(),
		nodeCount   = nodes.length,
		row, i, firstChild;

		this.updateHeaderWidth();
		headerCell.style.width = columnWidth;

		for (i = 0; i < nodeCount; i++) {
			row = nodes[i];
			firstChild = row.firstChild;

			row.style.width = totalWidth;
			if (firstChild) {
				firstChild.style.width = totalWidth;
				firstChild.rows[0].childNodes[column].style.width = columnWidth;
			}
		}

		this.onColumnWidthUpdated(column, columnWidth, totalWidth);
	},


	updateColumnHidden : function(col, hidden) {
		var totalWidth = this.getTotalWidth(),
		display    = hidden ? 'none' : '',
		headerCell = this.getHeaderCell(col),
		nodes      = this.getRows(),
		nodeCount  = nodes.length,
		row, rowFirstChild, i;

		this.updateHeaderWidth();
		headerCell.style.display = display;

		for (i = 0; i < nodeCount; i++) {
			row = nodes[i];
			row.style.width = totalWidth;
			rowFirstChild = row.firstChild;

			if (rowFirstChild) {
				rowFirstChild.style.width = totalWidth;
				rowFirstChild.rows[0].childNodes[col].style.display = display;
			}
		}

		this.onColumnHiddenUpdated(col, hidden, totalWidth);
		delete this.lastViewWidth;
		this.layout();
	},


	doRender : function(columns, records, store, startRow, colCount, stripe) {
		var templates = this.templates,
		cellTemplate = templates.cell,
		rowTemplate = templates.row,
		last = colCount - 1,
		tstyle = 'width:' + this.getTotalWidth() + ';',

		rowBuffer = [],
		colBuffer = [],
		rowParams = {
			tstyle: tstyle
		},
		meta = {},
		len  = records.length,
		alt,
		column,
		record, i, j, rowIndex;


		for (j = 0; j < len; j++) {
			record    = records[j];
			colBuffer = [];

			rowIndex = j + startRow;


			for (i = 0; i < colCount; i++) {
				column = columns[i];

				meta.id    = column.id;
				meta.css   = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
				meta.attr  = meta.cellAttr = '';
				meta.style = column.style;
				meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);

				if (Ext.isEmpty(meta.value)) {
					meta.value = '&#160;';
				}

				if (this.markDirty && record.dirty && typeof record.modified[column.name] != 'undefined') {
					meta.css += ' x-grid3-dirty-cell';
				}

				colBuffer[colBuffer.length] = cellTemplate.apply(meta);
			}

			alt = [];

			if (stripe && ((rowIndex + 1) % 2 === 0)) {
				alt[0] = 'x-grid3-row-alt';
			}

			if (record.dirty) {
				alt[1] = ' x-grid3-dirty-row';
			}

			rowParams.cols = colCount;

			if (this.getRowClass) {
				alt[2] = this.getRowClass(record, rowIndex, rowParams, store);
			}

			rowParams.alt   = alt.join(' ');
			rowParams.cells = colBuffer.join('');

			rowBuffer[rowBuffer.length] = rowTemplate.apply(rowParams);
		}

		return rowBuffer.join('');
	},


	processRows : function(startRow, skipStripe) {
		if (!this.ds || this.ds.getCount() < 1) {
			return;
		}

		var rows   = this.getRows(),
		length = rows.length,
		row, i;

		skipStripe = skipStripe || !this.grid.stripeRows;
		startRow   = startRow   || 0;

		for (i = 0; i < length; i++) {
			row = rows[i];
			if (row) {
				row.rowIndex = i;
				if (!skipStripe) {
					row.className = row.className.replace(this.rowClsRe, ' ');
					if ((i + 1) % 2 === 0){
						row.className += ' x-grid3-row-alt';
					}
				}
			}
		}


		if (startRow === 0) {
			Ext.fly(rows[0]).addClass(this.firstRowCls);
		}

		Ext.fly(rows[length - 1]).addClass(this.lastRowCls);
	},


	afterRender : function() {
		if (!this.ds || !this.cm) {
			return;
		}

		this.mainBody.dom.innerHTML = this.renderBody() || '&#160;';
		this.processRows(0, true);

		if (this.deferEmptyText !== true) {
			this.applyEmptyText();
		}

		this.grid.fireEvent('viewready', this.grid);
	},


	afterRenderUI: function() {
		var grid = this.grid;

		this.initElements();


		Ext.fly(this.innerHd).on('click', this.handleHdDown, this);

		this.mainHd.on({
			scope    : this,
			mouseover: this.handleHdOver,
			mouseout : this.handleHdOut,
			mousemove: this.handleHdMove
		});

		this.scroller.on('scroll', this.syncScroll,  this);

		if (grid.enableColumnResize !== false) {
			this.splitZone = new Ext.grid.GridView.SplitDragZone(grid, this.mainHd.dom);
		}

		if (grid.enableColumnMove) {
			this.columnDrag = new Ext.grid.GridView.ColumnDragZone(grid, this.innerHd);
			this.columnDrop = new Ext.grid.HeaderDropZone(grid, this.mainHd.dom);
		}

		if (grid.enableHdMenu !== false) {
			this.hmenu = new Ext.menu.Menu({
				id: grid.id + '-hctx'
				});
			this.hmenu.add(
			{
				itemId:'asc',
				text: this.sortAscText,
				cls: 'xg-hmenu-sort-asc'
			},

			{
				itemId:'desc',
				text: this.sortDescText,
				cls: 'xg-hmenu-sort-desc'
			}
			);

			if (grid.enableColumnHide !== false) {
				this.colMenu = new Ext.menu.Menu({
					id:grid.id + '-hcols-menu'
					});
				this.colMenu.on({
					scope     : this,
					beforeshow: this.beforeColMenuShow,
					itemclick : this.handleHdMenuClick
				});
				this.hmenu.add('-', {
					itemId:'columns',
					hideOnClick: false,
					text: this.columnsText,
					menu: this.colMenu,
					iconCls: 'x-cols-icon'
				});
			}

			this.hmenu.on('itemclick', this.handleHdMenuClick, this);
		}

		if (grid.trackMouseOver) {
			this.mainBody.on({
				scope    : this,
				mouseover: this.onRowOver,
				mouseout : this.onRowOut
			});
		}

		if (grid.enableDragDrop || grid.enableDrag) {
			this.dragZone = new Ext.grid.GridDragZone(grid, {
				ddGroup : grid.ddGroup || 'GridDD'
			});
		}

		this.updateHeaderSortState();
	},


	renderUI : function() {
		var templates = this.templates;

		return templates.master.apply({
			body  : templates.body.apply({
				rows:'&#160;'
			}),
			header: this.renderHeaders(),
			ostyle: 'width:' + this.getOffsetWidth() + ';',
			bstyle: 'width:' + this.getTotalWidth()  + ';'
		});
	},


	processEvent : function(name, e) {
		var target = e.getTarget(),
		grid   = this.grid,
		header = this.findHeaderIndex(target),
		row, cell, col, body;

		grid.fireEvent(name, e);

		if (header !== false) {
			grid.fireEvent('header' + name, grid, header, e);
		} else {
			row = this.findRowIndex(target);




			if (row !== false) {
				cell = this.findCellIndex(target);
				if (cell !== false) {
					col = grid.colModel.getColumnAt(cell);
					if (grid.fireEvent('cell' + name, grid, row, cell, e) !== false) {
						if (!col || (col.processEvent && (col.processEvent(name, e, grid, row, cell) !== false))) {
							grid.fireEvent('row' + name, grid, row, e);
						}
					}
				} else {
					if (grid.fireEvent('row' + name, grid, row, e) !== false) {
						(body = this.findRowBody(target)) && grid.fireEvent('rowbody' + name, grid, row, e);
					}
				}
			} else {
				grid.fireEvent('container' + name, grid, e);
			}
		}
	},


	layout : function(initial) {
		if (!this.mainBody) {
			return;
		}

		var grid       = this.grid,
		gridEl     = grid.getGridEl(),
		gridSize   = gridEl.getSize(true),
		gridWidth  = gridSize.width,
		gridHeight = gridSize.height,
		scroller   = this.scroller,
		scrollStyle, headerHeight, scrollHeight;

		if (gridWidth < 20 || gridHeight < 20) {
			return;
		}

		if (grid.autoHeight) {
			scrollStyle = scroller.dom.style;
			scrollStyle.overflow = 'visible';

			if (Ext.isWebKit) {
				scrollStyle.position = 'static';
			}
		} else {
			this.el.setSize(gridWidth, gridHeight);

			headerHeight = this.mainHd.getHeight();
			scrollHeight = gridHeight - headerHeight;

			scroller.setSize(gridWidth, scrollHeight);

			if (this.innerHd) {
				this.innerHd.style.width = (gridWidth) + "px";
			}
		}

		if (this.forceFit || (initial === true && this.autoFill)) {
			if (this.lastViewWidth != gridWidth) {
				this.fitColumns(false, false);
				this.lastViewWidth = gridWidth;
			}
		} else {
			this.autoExpand();
			this.syncHeaderScroll();
		}

		this.onLayout(gridWidth, scrollHeight);
	},



	onLayout : function(vw, vh) {

	},

	onColumnWidthUpdated : function(col, w, tw) {

	},

	onAllColumnWidthsUpdated : function(ws, tw) {

	},

	onColumnHiddenUpdated : function(col, hidden, tw) {

	},

	updateColumnText : function(col, text) {

	},

	afterMove : function(colIndex) {

	},



	init : function(grid) {
		this.grid = grid;

		this.initTemplates();
		this.initData(grid.store, grid.colModel);
		this.initUI(grid);
	},


	getColumnId : function(index){
		return this.cm.getColumnId(index);
	},


	getOffsetWidth : function() {
		return (this.cm.getTotalWidth() + this.getScrollOffset()) + 'px';
	},


	getScrollOffset: function() {
		return Ext.num(this.scrollOffset, Ext.getScrollBarWidth());
	},


	renderHeaders : function() {
		var colModel   = this.cm,
		templates  = this.templates,
		headerTpl  = templates.hcell,
		properties = {},
		colCount   = colModel.getColumnCount(),
		last       = colCount - 1,
		cells      = [],
		i, cssCls;

		for (i = 0; i < colCount; i++) {
			if (i == 0) {
				cssCls = 'x-grid3-cell-first ';
			} else {
				cssCls = i == last ? 'x-grid3-cell-last ' : '';
			}

			properties = {
				id     : colModel.getColumnId(i),
				value  : colModel.getColumnHeader(i) || '',
				style  : this.getColumnStyle(i, true),
				css    : cssCls,
				tooltip: this.getColumnTooltip(i)
			};

			if (colModel.config[i].align == 'right') {
				properties.istyle = 'padding-right: 16px;';
			} else {
				delete properties.istyle;
			}

			cells[i] = headerTpl.apply(properties);
		}

		return templates.header.apply({
			cells : cells.join(""),
			tstyle: String.format("width: {0};", this.getTotalWidth())
		});
	},


	getColumnTooltip : function(i) {
		var tooltip = this.cm.getColumnTooltip(i);
		if (tooltip) {
			if (Ext.QuickTips.isEnabled()) {
				return 'ext:qtip="' + tooltip + '"';
			} else {
				return 'title="' + tooltip + '"';
			}
		}

		return '';
	},


	beforeUpdate : function() {
		this.grid.stopEditing(true);
	},


	updateHeaders : function() {
		this.innerHd.firstChild.innerHTML = this.renderHeaders();

		this.updateHeaderWidth(false);
	},


	updateHeaderWidth: function(updateMain) {
		var innerHdChild = this.innerHd.firstChild,
		totalWidth   = this.getTotalWidth();

		innerHdChild.style.width = this.getOffsetWidth();
		innerHdChild.firstChild.style.width = totalWidth;

		if (updateMain !== false) {
			this.mainBody.dom.style.width = totalWidth;
		}
	},


	focusRow : function(row) {
		this.focusCell(row, 0, false);
	},


	focusCell : function(row, col, hscroll) {
		this.syncFocusEl(this.ensureVisible(row, col, hscroll));

		var focusEl = this.focusEl;

		if (Ext.isGecko) {
			focusEl.focus();
		} else {
			focusEl.focus.defer(1, focusEl);
		}
	},


	resolveCell : function(row, col, hscroll) {
		if (!Ext.isNumber(row)) {
			row = row.rowIndex;
		}

		if (!this.ds) {
			return null;
		}

		if (row < 0 || row >= this.ds.getCount()) {
			return null;
		}
		col = (col !== undefined ? col : 0);

		var rowEl    = this.getRow(row),
		colModel = this.cm,
		colCount = colModel.getColumnCount(),
		cellEl;

		if (!(hscroll === false && col === 0)) {
			while (col < colCount && colModel.isHidden(col)) {
				col++;
			}

			cellEl = this.getCell(row, col);
		}

		return {
			row: rowEl,
			cell: cellEl
		};
	},


	getResolvedXY : function(resolved) {
		if (!resolved) {
			return null;
		}

		var cell = resolved.cell,
		row  = resolved.row;

		if (cell) {
			return Ext.fly(cell).getXY();
		} else {
			return [this.el.getX(), Ext.fly(row).getY()];
		}
	},


	syncFocusEl : function(row, col, hscroll) {
		var xy = row;

		if (!Ext.isArray(xy)) {
			row = Math.min(row, Math.max(0, this.getRows().length-1));

			if (isNaN(row)) {
				return;
			}

			xy = this.getResolvedXY(this.resolveCell(row, col, hscroll));
		}

		this.focusEl.setXY(xy || this.scroller.getXY());
	},


	ensureVisible : function(row, col, hscroll) {
		var resolved = this.resolveCell(row, col, hscroll);

		if (!resolved || !resolved.row) {
			return null;
		}

		var rowEl  = resolved.row,
		cellEl = resolved.cell,
		c = this.scroller.dom,
		p = rowEl,
		ctop = 0,
		stop = this.el.dom;

		while (p && p != stop) {
			ctop += p.offsetTop;
			p = p.offsetParent;
		}

		ctop -= this.mainHd.dom.offsetHeight;
		stop = parseInt(c.scrollTop, 10);

		var cbot = ctop + rowEl.offsetHeight,
		ch = c.clientHeight,
		sbot = stop + ch;


		if (ctop < stop) {
			c.scrollTop = ctop;
		} else if(cbot > sbot) {
			c.scrollTop = cbot-ch;
		}

		if (hscroll !== false) {
			var cleft  = parseInt(cellEl.offsetLeft, 10),
			cright = cleft + cellEl.offsetWidth,
			sleft  = parseInt(c.scrollLeft, 10),
			sright = sleft + c.clientWidth;

			if (cleft < sleft) {
				c.scrollLeft = cleft;
			} else if(cright > sright) {
				c.scrollLeft = cright-c.clientWidth;
			}
		}

		return this.getResolvedXY(resolved);
	},


	insertRows : function(dm, firstRow, lastRow, isUpdate) {
		var last = dm.getCount() - 1;
		if( !isUpdate && firstRow === 0 && lastRow >= last) {
			this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
			this.refresh();
			this.fireEvent('rowsinserted', this, firstRow, lastRow);
		} else {
			if (!isUpdate) {
				this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
			}
			var html = this.renderRows(firstRow, lastRow),
			before = this.getRow(firstRow);
			if (before) {
				if(firstRow === 0){
					Ext.fly(this.getRow(0)).removeClass(this.firstRowCls);
				}
				Ext.DomHelper.insertHtml('beforeBegin', before, html);
			} else {
				var r = this.getRow(last - 1);
				if(r){
					Ext.fly(r).removeClass(this.lastRowCls);
				}
				Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html);
			}
			if (!isUpdate) {
				this.processRows(firstRow);
				this.fireEvent('rowsinserted', this, firstRow, lastRow);
			} else if (firstRow === 0 || firstRow >= last) {

				Ext.fly(this.getRow(firstRow)).addClass(firstRow === 0 ? this.firstRowCls : this.lastRowCls);
			}
		}
		this.syncFocusEl(firstRow);
	},


	deleteRows : function(dm, firstRow, lastRow) {
		if (dm.getRowCount() < 1) {
			this.refresh();
		} else {
			this.fireEvent('beforerowsdeleted', this, firstRow, lastRow);

			this.removeRows(firstRow, lastRow);

			this.processRows(firstRow);
			this.fireEvent('rowsdeleted', this, firstRow, lastRow);
		}
	},


	getColumnStyle : function(colIndex, isHeader) {
		var colModel  = this.cm,
		colConfig = colModel.config,
		style     = isHeader ? '' : colConfig[colIndex].css || '',
		align     = colConfig[colIndex].align;

		style += String.format("width: {0};", this.getColumnWidth(colIndex));

		if (colModel.isHidden(colIndex)) {
			style += 'display: none; ';
		}

		if (align) {
			style += String.format("text-align: {0};", align);
		}

		return style;
	},


	getColumnWidth : function(column) {
		var columnWidth = this.cm.getColumnWidth(column),
		borderWidth = this.borderWidth;

		if (Ext.isNumber(columnWidth)) {
			if (Ext.isBorderBox || (Ext.isWebKit && !Ext.isSafari2)) {
				return columnWidth + "px";
			} else {
				return Math.max(columnWidth - borderWidth, 0) + "px";
			}
		} else {
			return columnWidth;
		}
	},


	getTotalWidth : function() {
		return this.cm.getTotalWidth() + 'px';
	},


	fitColumns : function(preventRefresh, onlyExpand, omitColumn) {
		var grid          = this.grid,
		colModel      = this.cm,
		totalColWidth = colModel.getTotalWidth(false),
		gridWidth     = this.getGridInnerWidth(),
		extraWidth    = gridWidth - totalColWidth,
		columns       = [],
		extraCol      = 0,
		width         = 0,
		colWidth, fraction, i;


		if (gridWidth < 20 || extraWidth === 0) {
			return false;
		}

		var visibleColCount = colModel.getColumnCount(true),
		totalColCount   = colModel.getColumnCount(false),
		adjCount        = visibleColCount - (Ext.isNumber(omitColumn) ? 1 : 0);

		if (adjCount === 0) {
			adjCount = 1;
			omitColumn = undefined;
		}


		for (i = 0; i < totalColCount; i++) {
			if (!colModel.isFixed(i) && i !== omitColumn) {
				colWidth = colModel.getColumnWidth(i);
				columns.push(i, colWidth);

				if (!colModel.isHidden(i)) {
					extraCol = i;
					width += colWidth;
				}
			}
		}

		fraction = (gridWidth - colModel.getTotalWidth()) / width;

		while (columns.length) {
			colWidth = columns.pop();
			i        = columns.pop();

			colModel.setColumnWidth(i, Math.max(grid.minColumnWidth, Math.floor(colWidth + colWidth * fraction)), true);
		}


		totalColWidth = colModel.getTotalWidth(false);

		if (totalColWidth > gridWidth) {
			var adjustCol = (adjCount == visibleColCount) ? extraCol : omitColumn,
			newWidth  = Math.max(1, colModel.getColumnWidth(adjustCol) - (totalColWidth - gridWidth));

			colModel.setColumnWidth(adjustCol, newWidth, true);
		}

		if (preventRefresh !== true) {
			this.updateAllColumnWidths();
		}

		return true;
	},


	autoExpand : function(preventUpdate) {
		var grid             = this.grid,
		colModel         = this.cm,
		gridWidth        = this.getGridInnerWidth(),
		totalColumnWidth = colModel.getTotalWidth(false),
		autoExpandColumn = grid.autoExpandColumn;

		if (!this.userResized && autoExpandColumn) {
			if (gridWidth != totalColumnWidth) {

				var colIndex     = colModel.getIndexById(autoExpandColumn),
				currentWidth = colModel.getColumnWidth(colIndex),
				desiredWidth = gridWidth - totalColumnWidth + currentWidth,
				newWidth     = Math.min(Math.max(desiredWidth, grid.autoExpandMin), grid.autoExpandMax);

				if (currentWidth != newWidth) {
					colModel.setColumnWidth(colIndex, newWidth, true);

					if (preventUpdate !== true) {
						this.updateColumnWidth(colIndex, newWidth);
					}
				}
			}
		}
	},


	getGridInnerWidth: function() {
		return this.grid.getGridEl().getWidth(true) - this.getScrollOffset();
	},


	getColumnData : function() {
		var columns  = [],
		colModel = this.cm,
		colCount = colModel.getColumnCount(),
		fields   = this.ds.fields,
		i, name;

		for (i = 0; i < colCount; i++) {
			name = colModel.getDataIndex(i);

			columns[i] = {
				name    : Ext.isDefined(name) ? name : (fields.get(i) ? fields.get(i).name : undefined),
				renderer: colModel.getRenderer(i),
				scope   : colModel.getRendererScope(i),
				id      : colModel.getColumnId(i),
				style   : this.getColumnStyle(i)
			};
		}

		return columns;
	},


	renderRows : function(startRow, endRow) {
		var grid     = this.grid,
		store    = grid.store,
		stripe   = grid.stripeRows,
		colModel = grid.colModel,
		colCount = colModel.getColumnCount(),
		rowCount = store.getCount(),
		records;

		if (rowCount < 1) {
			return '';
		}

		startRow = startRow || 0;
		endRow   = Ext.isDefined(endRow) ? endRow : rowCount - 1;
		records  = store.getRange(startRow, endRow);

		return this.doRender(this.getColumnData(), records, store, startRow, colCount, stripe);
	},


	renderBody : function(){
		var markup = this.renderRows() || '&#160;';
		return this.templates.body.apply({
			rows: markup
		});
	},


	refreshRow: function(record) {
		var store     = this.ds,
		colCount  = this.cm.getColumnCount(),
		columns   = this.getColumnData(),
		last      = colCount - 1,
		cls       = ['x-grid3-row'],
		rowParams = {
			tstyle: String.format("width: {0};", this.getTotalWidth())
		},
		colBuffer = [],
		cellTpl   = this.templates.cell,
		rowIndex, row, column, meta, css, i;

		if (Ext.isNumber(record)) {
			rowIndex = record;
			record   = store.getAt(rowIndex);
		} else {
			rowIndex = store.indexOf(record);
		}


		if (!record || rowIndex < 0) {
			return;
		}


		for (i = 0; i < colCount; i++) {
			column = columns[i];

			if (i == 0) {
				css = 'x-grid3-cell-first';
			} else {
				css = (i == last) ? 'x-grid3-cell-last ' : '';
			}

			meta = {
				id      : column.id,
				style   : column.style,
				css     : css,
				attr    : "",
				cellAttr: ""
			};

			meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);

			if (Ext.isEmpty(meta.value)) {
				meta.value = '&#160;';
			}

			if (this.markDirty && record.dirty && typeof record.modified[column.name] != 'undefined') {
				meta.css += ' x-grid3-dirty-cell';
			}

			colBuffer[i] = cellTpl.apply(meta);
		}

		row = this.getRow(rowIndex);
		row.className = '';

		if (this.grid.stripeRows && ((rowIndex + 1) % 2 === 0)) {
			cls.push('x-grid3-row-alt');
		}

		if (this.getRowClass) {
			rowParams.cols = colCount;
			cls.push(this.getRowClass(record, rowIndex, rowParams, store));
		}

		this.fly(row).addClass(cls).setStyle(rowParams.tstyle);
		rowParams.cells = colBuffer.join("");
		row.innerHTML = this.templates.rowInner.apply(rowParams);

		this.fireEvent('rowupdated', this, rowIndex, record);
	},


	refresh : function(headersToo) {
		this.fireEvent('beforerefresh', this);
		this.grid.stopEditing(true);

		var result = this.renderBody();
		this.mainBody.update(result).setWidth(this.getTotalWidth());
		if (headersToo === true) {
			this.updateHeaders();
			this.updateHeaderSortState();
		}
		this.processRows(0, true);
		this.layout();
		this.applyEmptyText();
		this.fireEvent('refresh', this);
	},


	applyEmptyText : function() {
		if (this.emptyText && !this.hasRows()) {
			this.mainBody.update('<div class="x-grid-empty">' + this.emptyText + '</div>');
		}
	},


	updateHeaderSortState : function() {
		var state = this.ds.getSortState();
		if (!state) {
			return;
		}

		if (!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)) {
			this.grid.fireEvent('sortchange', this.grid, state);
		}

		this.sortState = state;

		var sortColumn = this.cm.findColumnIndex(state.field);
		if (sortColumn != -1) {
			var sortDir = state.direction;
			this.updateSortIcon(sortColumn, sortDir);
		}
	},


	clearHeaderSortState : function() {
		if (!this.sortState) {
			return;
		}
		this.grid.fireEvent('sortchange', this.grid, null);
		this.mainHd.select('td').removeClass(this.sortClasses);
		delete this.sortState;
	},


	destroy : function() {
		var me              = this,
		grid            = me.grid,
		gridEl          = grid.getGridEl(),
		dragZone        = me.dragZone,
		splitZone       = me.splitZone,
		columnDrag      = me.columnDrag,
		columnDrop      = me.columnDrop,
		scrollToTopTask = me.scrollToTopTask,
		columnDragData,
		columnDragProxy;

		if (scrollToTopTask && scrollToTopTask.cancel) {
			scrollToTopTask.cancel();
		}

		Ext.destroyMembers(me, 'colMenu', 'hmenu');

		me.initData(null, null);
		me.purgeListeners();

		Ext.fly(me.innerHd).un("click", me.handleHdDown, me);

		if (grid.enableColumnMove) {
			columnDragData = columnDrag.dragData;
			columnDragProxy = columnDrag.proxy;
			Ext.destroy(
				columnDrag.el,
				columnDragProxy.ghost,
				columnDragProxy.el,
				columnDrop.el,
				columnDrop.proxyTop,
				columnDrop.proxyBottom,
				columnDragData.ddel,
				columnDragData.header
				);

			if (columnDragProxy.anim) {
				Ext.destroy(columnDragProxy.anim);
			}

			delete columnDragProxy.ghost;
			delete columnDragData.ddel;
			delete columnDragData.header;
			columnDrag.destroy();

			delete Ext.dd.DDM.locationCache[columnDrag.id];
			delete columnDrag._domRef;

			delete columnDrop.proxyTop;
			delete columnDrop.proxyBottom;
			columnDrop.destroy();
			delete Ext.dd.DDM.locationCache["gridHeader" + gridEl.id];
			delete columnDrop._domRef;
			delete Ext.dd.DDM.ids[columnDrop.ddGroup];
		}

		if (splitZone) {
			splitZone.destroy();
			delete splitZone._domRef;
			delete Ext.dd.DDM.ids["gridSplitters" + gridEl.id];
		}

		Ext.fly(me.innerHd).removeAllListeners();
		Ext.removeNode(me.innerHd);
		delete me.innerHd;

		Ext.destroy(
			me.el,
			me.mainWrap,
			me.mainHd,
			me.scroller,
			me.mainBody,
			me.focusEl,
			me.resizeMarker,
			me.resizeProxy,
			me.activeHdBtn,
			me._flyweight,
			dragZone,
			splitZone
			);

		delete grid.container;

		if (dragZone) {
			dragZone.destroy();
		}

		Ext.dd.DDM.currentTarget = null;
		delete Ext.dd.DDM.locationCache[gridEl.id];

		Ext.EventManager.removeResizeListener(me.onWindowResize, me);
	},


	onDenyColumnHide : function() {

	},


	render : function() {
		if (this.autoFill) {
			var ct = this.grid.ownerCt;

			if (ct && ct.getLayout()) {
				ct.on('afterlayout', function() {
					this.fitColumns(true, true);
					this.updateHeaders();
					this.updateHeaderSortState();
				}, this, {
					single: true
				});
			}
		} else if (this.forceFit) {
			this.fitColumns(true, false);
		} else if (this.grid.autoExpandColumn) {
			this.autoExpand(true);
		}

		this.grid.getGridEl().dom.innerHTML = this.renderUI();

		this.afterRenderUI();
	},




	initData : function(newStore, newColModel) {
		var me = this;

		if (me.ds) {
			var oldStore = me.ds;

			oldStore.un('add', me.onAdd, me);
			oldStore.un('load', me.onLoad, me);
			oldStore.un('clear', me.onClear, me);
			oldStore.un('remove', me.onRemove, me);
			oldStore.un('update', me.onUpdate, me);
			oldStore.un('datachanged', me.onDataChange, me);

			if (oldStore !== newStore && oldStore.autoDestroy) {
				oldStore.destroy();
			}
		}

		if (newStore) {
			newStore.on({
				scope      : me,
				load       : me.onLoad,
				add        : me.onAdd,
				remove     : me.onRemove,
				update     : me.onUpdate,
				clear      : me.onClear,
				datachanged: me.onDataChange
			});
		}

		if (me.cm) {
			var oldColModel = me.cm;

			oldColModel.un('configchange', me.onColConfigChange, me);
			oldColModel.un('widthchange',  me.onColWidthChange, me);
			oldColModel.un('headerchange', me.onHeaderChange, me);
			oldColModel.un('hiddenchange', me.onHiddenChange, me);
			oldColModel.un('columnmoved',  me.onColumnMove, me);
		}

		if (newColModel) {
			delete me.lastViewWidth;

			newColModel.on({
				scope       : me,
				configchange: me.onColConfigChange,
				widthchange : me.onColWidthChange,
				headerchange: me.onHeaderChange,
				hiddenchange: me.onHiddenChange,
				columnmoved : me.onColumnMove
			});
		}

		me.ds = newStore;
		me.cm = newColModel;
	},


	onDataChange : function(){
		this.refresh(true);
		this.updateHeaderSortState();
		this.syncFocusEl(0);
	},


	onClear : function() {
		this.refresh();
		this.syncFocusEl(0);
	},


	onUpdate : function(store, record) {
		this.refreshRow(record);
	},


	onAdd : function(store, records, index) {
		this.insertRows(store, index, index + (records.length-1));
	},


	onRemove : function(store, record, index, isUpdate) {
		if (isUpdate !== true) {
			this.fireEvent('beforerowremoved', this, index, record);
		}

		this.removeRow(index);

		if (isUpdate !== true) {
			this.processRows(index);
			this.applyEmptyText();
			this.fireEvent('rowremoved', this, index, record);
		}
	},


	onLoad : function() {
		if (Ext.isGecko) {
			if (!this.scrollToTopTask) {
				this.scrollToTopTask = new Ext.util.DelayedTask(this.scrollToTop, this);
			}
			this.scrollToTopTask.delay(1);
		} else {
			this.scrollToTop();
		}
	},


	onColWidthChange : function(cm, col, width) {
		this.updateColumnWidth(col, width);
	},


	onHeaderChange : function(cm, col, text) {
		this.updateHeaders();
	},


	onHiddenChange : function(cm, col, hidden) {
		this.updateColumnHidden(col, hidden);
	},


	onColumnMove : function(cm, oldIndex, newIndex) {
		this.indexMap = null;
		this.refresh(true);
		this.restoreScroll(this.getScrollState());

		this.afterMove(newIndex);
		this.grid.fireEvent('columnmove', oldIndex, newIndex);
	},


	onColConfigChange : function() {
		delete this.lastViewWidth;
		this.indexMap = null;
		this.refresh(true);
	},



	initUI : function(grid) {
		grid.on('headerclick', this.onHeaderClick, this);
	},


	initEvents : Ext.emptyFn,


	onHeaderClick : function(g, index) {
		if (this.headersDisabled || !this.cm.isSortable(index)) {
			return;
		}
		g.stopEditing(true);
		g.store.sort(this.cm.getDataIndex(index));
	},


	onRowOver : function(e, target) {
		var row = this.findRowIndex(target);

		if (row !== false) {
			this.addRowClass(row, this.rowOverCls);
		}
	},


	onRowOut : function(e, target) {
		var row = this.findRowIndex(target);

		if (row !== false && !e.within(this.getRow(row), true)) {
			this.removeRowClass(row, this.rowOverCls);
		}
	},


	onRowSelect : function(row) {
		this.addRowClass(row, this.selectedRowClass);
	},


	onRowDeselect : function(row) {
		this.removeRowClass(row, this.selectedRowClass);
	},


	onCellSelect : function(row, col) {
		var cell = this.getCell(row, col);
		if (cell) {
			this.fly(cell).addClass('x-grid3-cell-selected');
		}
	},


	onCellDeselect : function(row, col) {
		var cell = this.getCell(row, col);
		if (cell) {
			this.fly(cell).removeClass('x-grid3-cell-selected');
		}
	},


	handleWheel : function(e) {
		e.stopPropagation();
	},


	onColumnSplitterMoved : function(cellIndex, width) {
		this.userResized = true;
		this.grid.colModel.setColumnWidth(cellIndex, width, true);

		if (this.forceFit) {
			this.fitColumns(true, false, cellIndex);
			this.updateAllColumnWidths();
		} else {
			this.updateColumnWidth(cellIndex, width);
			this.syncHeaderScroll();
		}

		this.grid.fireEvent('columnresize', cellIndex, width);
	},


	beforeColMenuShow : function() {
		var colModel = this.cm,
		colCount = colModel.getColumnCount(),
		colMenu  = this.colMenu,
		i;

		colMenu.removeAll();

		for (i = 0; i < colCount; i++) {
			if (colModel.config[i].hideable !== false) {
				colMenu.add(new Ext.menu.CheckItem({
					text       : colModel.getColumnHeader(i),
					itemId     : 'col-' + colModel.getColumnId(i),
					checked    : !colModel.isHidden(i),
					disabled   : colModel.config[i].hideable === false,
					hideOnClick: false
				}));
			}
		}
	},


	handleHdMenuClick : function(item) {
		var store     = this.ds,
		dataIndex = this.cm.getDataIndex(this.hdCtxIndex);

		switch (item.getItemId()) {
			case 'asc':
				store.sort(dataIndex, 'ASC');
				break;
			case 'desc':
				store.sort(dataIndex, 'DESC');
				break;
			default:
				this.handleHdMenuClickDefault(item);
		}
		return true;
	},


	handleHdMenuClickDefault: function(item) {
		var colModel = this.cm,
		itemId   = item.getItemId(),
		index    = colModel.getIndexById(itemId.substr(4));

		if (index != -1) {
			if (item.checked && colModel.getColumnsBy(this.isHideableColumn, this).length <= 1) {
				this.onDenyColumnHide();
				return;
			}
			colModel.setHidden(index, item.checked);
		}
	},


	handleHdDown : function(e, target) {
		if (Ext.fly(target).hasClass('x-grid3-hd-btn')) {
			e.stopEvent();

			var colModel  = this.cm,
			header    = this.findHeaderCell(target),
			index     = this.getCellIndex(header),
			sortable  = colModel.isSortable(index),
			menu      = this.hmenu,
			menuItems = menu.items,
			menuCls   = this.headerMenuOpenCls;

			this.hdCtxIndex = index;

			Ext.fly(header).addClass(menuCls);
			menuItems.get('asc').setDisabled(!sortable);
			menuItems.get('desc').setDisabled(!sortable);

			menu.on('hide', function() {
				Ext.fly(header).removeClass(menuCls);
			}, this, {
				single:true
			});

			menu.show(target, 'tl-bl?');
		}
	},


	handleHdMove : function(e) {
		var header = this.findHeaderCell(this.activeHdRef);

		if (header && !this.headersDisabled) {
			var handleWidth  = this.splitHandleWidth || 5,
			activeRegion = this.activeHdRegion,
			headerStyle  = header.style,
			colModel     = this.cm,
			cursor       = '',
			pageX        = e.getPageX();

			if (this.grid.enableColumnResize !== false) {
				var activeHeaderIndex = this.activeHdIndex,
				previousVisible   = this.getPreviousVisible(activeHeaderIndex),
				currentResizable  = colModel.isResizable(activeHeaderIndex),
				previousResizable = previousVisible && colModel.isResizable(previousVisible),
				inLeftResizer     = pageX - activeRegion.left <= handleWidth,
				inRightResizer    = activeRegion.right - pageX <= (!this.activeHdBtn ? handleWidth : 2);

				if (inLeftResizer && previousResizable) {
					cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'e-resize' : 'col-resize';
				} else if (inRightResizer && currentResizable) {
					cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'w-resize' : 'col-resize';
				}
			}

			headerStyle.cursor = cursor;
		}
	},


	getPreviousVisible: function(index) {
		while (index > 0) {
			if (!this.cm.isHidden(index - 1)) {
				return index;
			}
			index--;
		}
		return undefined;
	},


	handleHdOver : function(e, target) {
		var header = this.findHeaderCell(target);

		if (header && !this.headersDisabled) {
			var fly = this.fly(header);

			this.activeHdRef = target;
			this.activeHdIndex = this.getCellIndex(header);
			this.activeHdRegion = fly.getRegion();

			if (!this.isMenuDisabled(this.activeHdIndex, fly)) {
				fly.addClass('x-grid3-hd-over');
				this.activeHdBtn = fly.child('.x-grid3-hd-btn');

				if (this.activeHdBtn) {
					this.activeHdBtn.dom.style.height = (header.firstChild.offsetHeight - 1) + 'px';
				}
			}
		}
	},


	handleHdOut : function(e, target) {
		var header = this.findHeaderCell(target);

		if (header && (!Ext.isIE || !e.within(header, true))) {
			this.activeHdRef = null;
			this.fly(header).removeClass('x-grid3-hd-over');
			header.style.cursor = '';
		}
	},


	isMenuDisabled: function(cellIndex, el) {
		return this.cm.isMenuDisabled(cellIndex);
	},


	hasRows : function() {
		var fc = this.mainBody.dom.firstChild;
		return fc && fc.nodeType == 1 && fc.className != 'x-grid-empty';
	},


	isHideableColumn : function(c) {
		return !c.hidden;
	},


	bind : function(d, c) {
		this.initData(d, c);
	}
});




Ext.grid.GridView.SplitDragZone = Ext.extend(Ext.dd.DDProxy, {

	constructor: function(grid, hd){
		this.grid = grid;
		this.view = grid.getView();
		this.marker = this.view.resizeMarker;
		this.proxy = this.view.resizeProxy;
		Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this, hd,
			'gridSplitters' + this.grid.getGridEl().id, {
				dragElId : Ext.id(this.proxy.dom),
				resizeFrame:false
			});
		this.scroll = false;
		this.hw = this.view.splitHandleWidth || 5;
	},

	b4StartDrag : function(x, y){
		this.dragHeadersDisabled = this.view.headersDisabled;
		this.view.headersDisabled = true;
		var h = this.view.mainWrap.getHeight();
		this.marker.setHeight(h);
		this.marker.show();
		this.marker.alignTo(this.view.getHeaderCell(this.cellIndex), 'tl-tl', [-2, 0]);
		this.proxy.setHeight(h);
		var w = this.cm.getColumnWidth(this.cellIndex),
		minw = Math.max(w-this.grid.minColumnWidth, 0);
		this.resetConstraints();
		this.setXConstraint(minw, 1000);
		this.setYConstraint(0, 0);
		this.minX = x - minw;
		this.maxX = x + 1000;
		this.startPos = x;
		Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
	},

	allowHeaderDrag : function(e){
		return true;
	},

	handleMouseDown : function(e){
		var t = this.view.findHeaderCell(e.getTarget());
		if(t && this.allowHeaderDrag(e)){
			var xy = this.view.fly(t).getXY(),
			x = xy[0],
			exy = e.getXY(),
			ex = exy[0],
			w = t.offsetWidth,
			adjust = false;

			if((ex - x) <= this.hw){
				adjust = -1;
			}else if((x+w) - ex <= this.hw){
				adjust = 0;
			}
			if(adjust !== false){
				this.cm = this.grid.colModel;
				var ci = this.view.getCellIndex(t);
				if(adjust == -1){
					if (ci + adjust < 0) {
						return;
					}
					while(this.cm.isHidden(ci+adjust)){
						--adjust;
						if(ci+adjust < 0){
							return;
						}
					}
				}
				this.cellIndex = ci+adjust;
				this.split = t.dom;
				if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
					Ext.grid.GridView.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
				}
			}else if(this.view.columnDrag){
				this.view.columnDrag.callHandleMouseDown(e);
			}
		}
	},

	endDrag : function(e){
		this.marker.hide();
		var v = this.view,
		endX = Math.max(this.minX, e.getPageX()),
		diff = endX - this.startPos,
		disabled = this.dragHeadersDisabled;

		v.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
		setTimeout(function(){
			v.headersDisabled = disabled;
		}, 50);
	},

	autoOffset : function(){
		this.setDelta(0,0);
	}
});

Ext.grid.PivotGridView = Ext.extend(Ext.grid.GridView, {


	colHeaderCellCls: 'grid-hd-group-cell',


	title: '',




	getColumnHeaders: function() {
		return this.grid.topAxis.buildHeaders();;
	},


	getRowHeaders: function() {
		return this.grid.leftAxis.buildHeaders();
	},


	renderRows : function(startRow, endRow) {
		var grid          = this.grid,
		rows          = grid.extractData(),
		rowCount      = rows.length,
		templates     = this.templates,
		renderer      = grid.renderer,
		hasRenderer   = typeof renderer == 'function',
		getCellCls    = this.getCellCls,
		hasGetCellCls = typeof getCellCls == 'function',
		cellTemplate  = templates.cell,
		rowTemplate   = templates.row,
		rowBuffer     = [],
		meta          = {},
		tstyle        = 'width:' + this.getGridInnerWidth() + 'px;',
		colBuffer, column, i;

		startRow = startRow || 0;
		endRow   = Ext.isDefined(endRow) ? endRow : rowCount - 1;

		for (i = 0; i < rowCount; i++) {
			row = rows[i];
			colCount  = row.length;
			colBuffer = [];

			rowIndex = startRow + i;


			for (j = 0; j < colCount; j++) {
				cell = row[j];

				meta.css   = j === 0 ? 'x-grid3-cell-first ' : (j == (colCount - 1) ? 'x-grid3-cell-last ' : '');
				meta.attr  = meta.cellAttr = '';
				meta.value = cell;

				if (Ext.isEmpty(meta.value)) {
					meta.value = '&#160;';
				}

				if (hasRenderer) {
					meta.value = renderer(meta.value);
				}

				if (hasGetCellCls) {
					meta.css += getCellCls(meta.value) + ' ';
				}

				colBuffer[colBuffer.length] = cellTemplate.apply(meta);
			}

			rowBuffer[rowBuffer.length] = rowTemplate.apply({
				tstyle: tstyle,
				cols  : colCount,
				cells : colBuffer.join(""),
				alt   : ''
			});
		}

		return rowBuffer.join("");
	},


	masterTpl: new Ext.Template(
		'<div class="x-grid3 x-pivotgrid" hidefocus="true">',
		'<div class="x-grid3-viewport">',
		'<div class="x-grid3-header">',
		'<div class="x-grid3-header-title"><span>{title}</span></div>',
		'<div class="x-grid3-header-inner">',
		'<div class="x-grid3-header-offset" style="{ostyle}"></div>',
		'</div>',
		'<div class="x-clear"></div>',
		'</div>',
		'<div class="x-grid3-scroller">',
		'<div class="x-grid3-row-headers"></div>',
		'<div class="x-grid3-body" style="{bstyle}">{body}</div>',
		'<a href="#" class="x-grid3-focus" tabIndex="-1"></a>',
		'</div>',
		'</div>',
		'<div class="x-grid3-resize-marker">&#160;</div>',
		'<div class="x-grid3-resize-proxy">&#160;</div>',
		'</div>'
		),


	initTemplates: function() {
		Ext.grid.PivotGridView.superclass.initTemplates.apply(this, arguments);

		var templates = this.templates || {};
		if (!templates.gcell) {
			templates.gcell = new Ext.XTemplate(
				'<td class="x-grid3-hd x-grid3-gcell x-grid3-td-{id} ux-grid-hd-group-row-{row} ' + this.colHeaderCellCls + '" style="{style}">',
				'<div {tooltip} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">',
				this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '', '{value}',
				'</div>',
				'</td>'
				);
		}

		this.templates = templates;
		this.hrowRe = new RegExp("ux-grid-hd-group-row-(\\d+)", "");
	},


	initElements: function() {
		Ext.grid.PivotGridView.superclass.initElements.apply(this, arguments);


		this.rowHeadersEl = new Ext.Element(this.scroller.child('div.x-grid3-row-headers'));


		this.headerTitleEl = new Ext.Element(this.mainHd.child('div.x-grid3-header-title'));
	},


	getGridInnerWidth: function() {
		var previousWidth = Ext.grid.PivotGridView.superclass.getGridInnerWidth.apply(this, arguments);

		return previousWidth - this.getTotalRowHeaderWidth();
	},


	getTotalRowHeaderWidth: function() {
		var headers = this.getRowHeaders(),
		length  = headers.length,
		total   = 0,
		i;

		for (i = 0; i< length; i++) {
			total += headers[i].width;
		}

		return total;
	},


	getTotalColumnHeaderHeight: function() {
		return this.getColumnHeaders().length * 21;
	},


	renderUI : function() {
		var templates  = this.templates,
		innerWidth = this.getGridInnerWidth();

		return templates.master.apply({
			body  : templates.body.apply({
				rows:'&#160;'
			}),
			ostyle: 'width:' + innerWidth + 'px',
			bstyle: 'width:' + innerWidth + 'px'
		});
	},


	onLayout: function(width, height) {
		Ext.grid.PivotGridView.superclass.onLayout.apply(this, arguments);

		var width = this.getGridInnerWidth();

		this.resizeColumnHeaders(width);
		this.resizeAllRows(width);
	},


	refresh : function(headersToo) {
		this.fireEvent('beforerefresh', this);
		this.grid.stopEditing(true);

		var result = this.renderBody();
		this.mainBody.update(result).setWidth(this.getGridInnerWidth());
		if (headersToo === true) {
			this.updateHeaders();
			this.updateHeaderSortState();
		}
		this.processRows(0, true);
		this.layout();
		this.applyEmptyText();
		this.fireEvent('refresh', this);
	},


	renderHeaders: Ext.emptyFn,


	fitColumns: Ext.emptyFn,


	resizeColumnHeaders: function(width) {
		var topAxis = this.grid.topAxis;

		if (topAxis.rendered) {
			topAxis.el.setWidth(width);
		}
	},


	resizeRowHeaders: function() {
		var rowHeaderWidth = this.getTotalRowHeaderWidth(),
		marginStyle    = String.format("margin-left: {0}px;", rowHeaderWidth);

		this.rowHeadersEl.setWidth(rowHeaderWidth);
		this.mainBody.applyStyles(marginStyle);
		Ext.fly(this.innerHd).applyStyles(marginStyle);

		this.headerTitleEl.setWidth(rowHeaderWidth);
		this.headerTitleEl.setHeight(this.getTotalColumnHeaderHeight());
	},


	resizeAllRows: function(width) {
		var rows   = this.getRows(),
		length = rows.length,
		i;

		for (i = 0; i < length; i++) {
			Ext.fly(rows[i]).setWidth(width);
			Ext.fly(rows[i]).child('table').setWidth(width);
		}
	},


	updateHeaders: function() {
		this.renderGroupRowHeaders();
		this.renderGroupColumnHeaders();
	},


	renderGroupRowHeaders: function() {
		var leftAxis = this.grid.leftAxis;

		this.resizeRowHeaders();
		leftAxis.rendered = false;
		leftAxis.render(this.rowHeadersEl);

		this.setTitle(this.title);
	},


	setTitle: function(title) {
		this.headerTitleEl.child('span').dom.innerHTML = title;
	},


	renderGroupColumnHeaders: function() {
		var topAxis = this.grid.topAxis;

		topAxis.rendered = false;
		topAxis.render(this.innerHd.firstChild);
	},


	isMenuDisabled: function(cellIndex, el) {
		return true;
	}
});
Ext.grid.PivotAxis = Ext.extend(Ext.Component, {

	orientation: 'horizontal',


	defaultHeaderWidth: 80,


	paddingWidth: 7,


	setDimensions: function(dimensions) {
		this.dimensions = dimensions;
	},


	onRender: function(ct, position) {
		var rows = this.orientation == 'horizontal'
		? this.renderHorizontalRows()
		: this.renderVerticalRows();

		this.el = Ext.DomHelper.overwrite(ct.dom, {
			tag: 'table',
			cn: rows
		}, true);
	},


	renderHorizontalRows: function() {
		var headers  = this.buildHeaders(),
		rowCount = headers.length,
		rows     = [],
		cells, cols, colCount, i, j;

		for (i = 0; i < rowCount; i++) {
			cells = [];
			cols  = headers[i].items;
			colCount = cols.length;

			for (j = 0; j < colCount; j++) {
				cells.push({
					tag: 'td',
					html: cols[j].header,
					colspan: cols[j].span
				});
			}

			rows[i] = {
				tag: 'tr',
				cn: cells
			};
		}

		return rows;
	},


	renderVerticalRows: function() {
		var headers  = this.buildHeaders(),
		colCount = headers.length,
		rowCells = [],
		rows     = [],
		rowCount, col, row, colWidth, i, j;

		for (i = 0; i < colCount; i++) {
			col = headers[i];
			colWidth = col.width || 80;
			rowCount = col.items.length;

			for (j = 0; j < rowCount; j++) {
				row = col.items[j];

				rowCells[row.start] = rowCells[row.start] || [];
				rowCells[row.start].push({
					tag    : 'td',
					html   : row.header,
					rowspan: row.span,
					width  : Ext.isBorderBox ? colWidth : colWidth - this.paddingWidth
				});
			}
		}

		rowCount = rowCells.length;
		for (i = 0; i < rowCount; i++) {
			rows[i] = {
				tag: 'tr',
				cn : rowCells[i]
			};
		}

		return rows;
	},


	getTuples: function() {
		var newStore = new Ext.data.Store({});

		newStore.data = this.store.data.clone();
		newStore.fields = this.store.fields;

		var sorters    = [],
		dimensions = this.dimensions,
		length     = dimensions.length,
		i;

		for (i = 0; i < length; i++) {
			sorters.push({
				field    : dimensions[i].dataIndex,
				direction: dimensions[i].direction || 'ASC'
			});
		}

		newStore.sort(sorters);

		var records = newStore.data.items,
		hashes  = [],
		tuples  = [],
		recData, hash, info, data, key;

		length = records.length;

		for (i = 0; i < length; i++) {
			info = this.getRecordInfo(records[i]);
			data = info.data;
			hash = "";

			for (key in data) {
				hash += data[key] + '---';
			}

			if (hashes.indexOf(hash) == -1) {
				hashes.push(hash);
				tuples.push(info);
			}
		}

		newStore.destroy();

		return tuples;
	},


	getRecordInfo: function(record) {
		var dimensions = this.dimensions,
		length  = dimensions.length,
		data    = {},
		dimension, dataIndex, i;


		for (i = 0; i < length; i++) {
			dimension = dimensions[i];
			dataIndex = dimension.dataIndex;

			data[dataIndex] = record.get(dataIndex);
		}



		var createMatcherFunction = function(data) {
			return function(record) {
				for (var dataIndex in data) {
					if (record.get(dataIndex) != data[dataIndex]) {
						return false;
					}
				}

				return true;
			};
		};

		return {
			data: data,
			matcher: createMatcherFunction(data)
		};
	},


	buildHeaders: function() {
		var tuples     = this.getTuples(),
		rowCount   = tuples.length,
		dimensions = this.dimensions,
		colCount   = dimensions.length,
		headers    = [],
		tuple, rows, currentHeader, previousHeader, span, start, isLast, changed, i, j;

		for (i = 0; i < colCount; i++) {
			dimension = dimensions[i];
			rows  = [];
			span  = 0;
			start = 0;

			for (j = 0; j < rowCount; j++) {
				tuple  = tuples[j];
				isLast = j == (rowCount - 1);
				currentHeader = tuple.data[dimension.dataIndex];


				changed = previousHeader != undefined && previousHeader != currentHeader;
				if (i > 0 && j > 0) {
					changed = changed || tuple.data[dimensions[i-1].dataIndex] != tuples[j-1].data[dimensions[i-1].dataIndex];
				}

				if (changed) {
					rows.push({
						header: previousHeader,
						span  : span,
						start : start
					});

					start += span;
					span = 0;
				}

				if (isLast) {
					rows.push({
						header: currentHeader,
						span  : span + 1,
						start : start
					});

					start += span;
					span = 0;
				}

				previousHeader = currentHeader;
				span++;
			}

			headers.push({
				items: rows,
				width: dimension.width || this.defaultHeaderWidth
			});

			previousHeader = undefined;
		}

		return headers;
	}
});


Ext.grid.HeaderDragZone = Ext.extend(Ext.dd.DragZone, {
	maxDragWidth: 120,

	constructor : function(grid, hd, hd2){
		this.grid = grid;
		this.view = grid.getView();
		this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
		Ext.grid.HeaderDragZone.superclass.constructor.call(this, hd);
		if(hd2){
			this.setHandleElId(Ext.id(hd));
			this.setOuterHandleElId(Ext.id(hd2));
		}
		this.scroll = false;
	},

	getDragData : function(e){
		var t = Ext.lib.Event.getTarget(e),
		h = this.view.findHeaderCell(t);
		if(h){
			return {
				ddel: h.firstChild,
				header:h
			};
		}
		return false;
	},

	onInitDrag : function(e){

		this.dragHeadersDisabled = this.view.headersDisabled;
		this.view.headersDisabled = true;
		var clone = this.dragData.ddel.cloneNode(true);
		clone.id = Ext.id();
		clone.style.width = Math.min(this.dragData.header.offsetWidth,this.maxDragWidth) + "px";
		this.proxy.update(clone);
		return true;
	},

	afterValidDrop : function(){
		this.completeDrop();
	},

	afterInvalidDrop : function(){
		this.completeDrop();
	},

	completeDrop: function(){
		var v = this.view,
		disabled = this.dragHeadersDisabled;
		setTimeout(function(){
			v.headersDisabled = disabled;
		}, 50);
	}
});



Ext.grid.HeaderDropZone = Ext.extend(Ext.dd.DropZone, {
	proxyOffsets : [-4, -9],
	fly: Ext.Element.fly,

	constructor : function(grid, hd, hd2){
		this.grid = grid;
		this.view = grid.getView();

		this.proxyTop = Ext.DomHelper.append(document.body, {
			cls:"col-move-top",
			html:"&#160;"
		}, true);
		this.proxyBottom = Ext.DomHelper.append(document.body, {
			cls:"col-move-bottom",
			html:"&#160;"
		}, true);
		this.proxyTop.hide = this.proxyBottom.hide = function(){
			this.setLeftTop(-100,-100);
			this.setStyle("visibility", "hidden");
		};
		this.ddGroup = "gridHeader" + this.grid.getGridEl().id;


		Ext.grid.HeaderDropZone.superclass.constructor.call(this, grid.getGridEl().dom);
	},

	getTargetFromEvent : function(e){
		var t = Ext.lib.Event.getTarget(e),
		cindex = this.view.findCellIndex(t);
		if(cindex !== false){
			return this.view.getHeaderCell(cindex);
		}
	},

	nextVisible : function(h){
		var v = this.view, cm = this.grid.colModel;
		h = h.nextSibling;
		while(h){
			if(!cm.isHidden(v.getCellIndex(h))){
				return h;
			}
			h = h.nextSibling;
		}
		return null;
	},

	prevVisible : function(h){
		var v = this.view, cm = this.grid.colModel;
		h = h.prevSibling;
		while(h){
			if(!cm.isHidden(v.getCellIndex(h))){
				return h;
			}
			h = h.prevSibling;
		}
		return null;
	},

	positionIndicator : function(h, n, e){
		var x = Ext.lib.Event.getPageX(e),
		r = Ext.lib.Dom.getRegion(n.firstChild),
		px,
		pt,
		py = r.top + this.proxyOffsets[1];
		if((r.right - x) <= (r.right-r.left)/2){
			px = r.right+this.view.borderWidth;
			pt = "after";
		}else{
			px = r.left;
			pt = "before";
		}

		if(this.grid.colModel.isFixed(this.view.getCellIndex(n))){
			return false;
		}

		px +=  this.proxyOffsets[0];
		this.proxyTop.setLeftTop(px, py);
		this.proxyTop.show();
		if(!this.bottomOffset){
			this.bottomOffset = this.view.mainHd.getHeight();
		}
		this.proxyBottom.setLeftTop(px, py+this.proxyTop.dom.offsetHeight+this.bottomOffset);
		this.proxyBottom.show();
		return pt;
	},

	onNodeEnter : function(n, dd, e, data){
		if(data.header != n){
			this.positionIndicator(data.header, n, e);
		}
	},

	onNodeOver : function(n, dd, e, data){
		var result = false;
		if(data.header != n){
			result = this.positionIndicator(data.header, n, e);
		}
		if(!result){
			this.proxyTop.hide();
			this.proxyBottom.hide();
		}
		return result ? this.dropAllowed : this.dropNotAllowed;
	},

	onNodeOut : function(n, dd, e, data){
		this.proxyTop.hide();
		this.proxyBottom.hide();
	},

	onNodeDrop : function(n, dd, e, data){
		var h = data.header;
		if(h != n){
			var cm = this.grid.colModel,
			x = Ext.lib.Event.getPageX(e),
			r = Ext.lib.Dom.getRegion(n.firstChild),
			pt = (r.right - x) <= ((r.right-r.left)/2) ? "after" : "before",
			oldIndex = this.view.getCellIndex(h),
			newIndex = this.view.getCellIndex(n);
			if(pt == "after"){
				newIndex++;
			}
			if(oldIndex < newIndex){
				newIndex--;
			}
			cm.moveColumn(oldIndex, newIndex);
			return true;
		}
		return false;
	}
});

Ext.grid.GridView.ColumnDragZone = Ext.extend(Ext.grid.HeaderDragZone, {

	constructor : function(grid, hd){
		Ext.grid.GridView.ColumnDragZone.superclass.constructor.call(this, grid, hd, null);
		this.proxy.el.addClass('x-grid3-col-dd');
	},

	handleMouseDown : function(e){
	},

	callHandleMouseDown : function(e){
		Ext.grid.GridView.ColumnDragZone.superclass.handleMouseDown.call(this, e);
	}
});

Ext.grid.SplitDragZone = Ext.extend(Ext.dd.DDProxy, {
	fly: Ext.Element.fly,

	constructor : function(grid, hd, hd2){
		this.grid = grid;
		this.view = grid.getView();
		this.proxy = this.view.resizeProxy;
		Ext.grid.SplitDragZone.superclass.constructor.call(this, hd,
			"gridSplitters" + this.grid.getGridEl().id, {
				dragElId : Ext.id(this.proxy.dom),
				resizeFrame:false
			});
		this.setHandleElId(Ext.id(hd));
		this.setOuterHandleElId(Ext.id(hd2));
		this.scroll = false;
	},

	b4StartDrag : function(x, y){
		this.view.headersDisabled = true;
		this.proxy.setHeight(this.view.mainWrap.getHeight());
		var w = this.cm.getColumnWidth(this.cellIndex);
		var minw = Math.max(w-this.grid.minColumnWidth, 0);
		this.resetConstraints();
		this.setXConstraint(minw, 1000);
		this.setYConstraint(0, 0);
		this.minX = x - minw;
		this.maxX = x + 1000;
		this.startPos = x;
		Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
	},


	handleMouseDown : function(e){
		var ev = Ext.EventObject.setEvent(e);
		var t = this.fly(ev.getTarget());
		if(t.hasClass("x-grid-split")){
			this.cellIndex = this.view.getCellIndex(t.dom);
			this.split = t.dom;
			this.cm = this.grid.colModel;
			if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
				Ext.grid.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
			}
		}
	},

	endDrag : function(e){
		this.view.headersDisabled = false;
		var endX = Math.max(this.minX, Ext.lib.Event.getPageX(e));
		var diff = endX - this.startPos;
		this.view.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
	},

	autoOffset : function(){
		this.setDelta(0,0);
	}
});
Ext.grid.GridDragZone = function(grid, config){
	this.view = grid.getView();
	Ext.grid.GridDragZone.superclass.constructor.call(this, this.view.mainBody.dom, config);
	this.scroll = false;
	this.grid = grid;
	this.ddel = document.createElement('div');
	this.ddel.className = 'x-grid-dd-wrap';
};

Ext.extend(Ext.grid.GridDragZone, Ext.dd.DragZone, {
	ddGroup : "GridDD",


	getDragData : function(e){
		var t = Ext.lib.Event.getTarget(e);
		var rowIndex = this.view.findRowIndex(t);
		if(rowIndex !== false){
			var sm = this.grid.selModel;
			if(!sm.isSelected(rowIndex) || e.hasModifier()){
				sm.handleMouseDown(this.grid, rowIndex, e);
			}
			return {
				grid: this.grid,
				ddel: this.ddel,
				rowIndex: rowIndex,
				selections:sm.getSelections()
				};
		}
		return false;
	},


	onInitDrag : function(e){
		var data = this.dragData;
		this.ddel.innerHTML = this.grid.getDragDropText();
		this.proxy.update(this.ddel);

	},


	afterRepair : function(){
		this.dragging = false;
	},


	getRepairXY : function(e, data){
		return false;
	},

	onEndDrag : function(data, e){

	},

	onValidDrop : function(dd, e, id){

		this.hideProxy();
	},

	beforeInvalidDrop : function(e, id){

	}
});

Ext.grid.ColumnModel = Ext.extend(Ext.util.Observable, {

	defaultWidth: 100,


	defaultSortable: false,





	constructor : function(config) {

		if (config.columns) {
			Ext.apply(this, config);
			this.setConfig(config.columns, true);
		} else {
			this.setConfig(config, true);
		}

		this.addEvents(

			"widthchange",


			"headerchange",


			"hiddenchange",


			"columnmoved",


			"configchange"
			);

		Ext.grid.ColumnModel.superclass.constructor.call(this);
	},


	getColumnId : function(index) {
		return this.config[index].id;
	},

	getColumnAt : function(index) {
		return this.config[index];
	},


	setConfig : function(config, initial) {
		var i, c, len;

		if (!initial) {
			delete this.totalWidth;

			for (i = 0, len = this.config.length; i < len; i++) {
				c = this.config[i];

				if (c.setEditor) {

					c.setEditor(null);
				}
			}
		}


		this.defaults = Ext.apply({
			width: this.defaultWidth,
			sortable: this.defaultSortable
		}, this.defaults);

		this.config = config;
		this.lookup = {};

		for (i = 0, len = config.length; i < len; i++) {
			c = Ext.applyIf(config[i], this.defaults);


			if (Ext.isEmpty(c.id)) {
				c.id = i;
			}

			if (!c.isColumn) {
				var Cls = Ext.grid.Column.types[c.xtype || 'gridcolumn'];
				c = new Cls(c);
				config[i] = c;
			}

			this.lookup[c.id] = c;
		}

		if (!initial) {
			this.fireEvent('configchange', this);
		}
	},


	getColumnById : function(id) {
		return this.lookup[id];
	},


	getIndexById : function(id) {
		for (var i = 0, len = this.config.length; i < len; i++) {
			if (this.config[i].id == id) {
				return i;
			}
		}
		return -1;
	},


	moveColumn : function(oldIndex, newIndex) {
		var config = this.config,
		c      = config[oldIndex];

		config.splice(oldIndex, 1);
		config.splice(newIndex, 0, c);
		this.dataMap = null;
		this.fireEvent("columnmoved", this, oldIndex, newIndex);
	},


	getColumnCount : function(visibleOnly) {
		var length = this.config.length,
		c = 0,
		i;

		if (visibleOnly === true) {
			for (i = 0; i < length; i++) {
				if (!this.isHidden(i)) {
					c++;
				}
			}

			return c;
		}

		return length;
	},


	getColumnsBy : function(fn, scope) {
		var config = this.config,
		length = config.length,
		result = [],
		i, c;

		for (i = 0; i < length; i++){
			c = config[i];

			if (fn.call(scope || this, c, i) === true) {
				result[result.length] = c;
			}
		}

		return result;
	},


	isSortable : function(col) {
		return !!this.config[col].sortable;
	},


	isMenuDisabled : function(col) {
		return !!this.config[col].menuDisabled;
	},


	getRenderer : function(col) {
		return this.config[col].renderer || Ext.grid.ColumnModel.defaultRenderer;
	},

	getRendererScope : function(col) {
		return this.config[col].scope;
	},


	setRenderer : function(col, fn) {
		this.config[col].renderer = fn;
	},


	getColumnWidth : function(col) {
		var width = this.config[col].width;
		if(typeof width != 'number'){
			width = this.defaultWidth;
		}
		return width;
	},


	setColumnWidth : function(col, width, suppressEvent) {
		this.config[col].width = width;
		this.totalWidth = null;

		if (!suppressEvent) {
			this.fireEvent("widthchange", this, col, width);
		}
	},


	getTotalWidth : function(includeHidden) {
		if (!this.totalWidth) {
			this.totalWidth = 0;
			for (var i = 0, len = this.config.length; i < len; i++) {
				if (includeHidden || !this.isHidden(i)) {
					this.totalWidth += this.getColumnWidth(i);
				}
			}
		}
		return this.totalWidth;
	},


	getColumnHeader : function(col) {
		return this.config[col].header;
	},


	setColumnHeader : function(col, header) {
		this.config[col].header = header;
		this.fireEvent("headerchange", this, col, header);
	},


	getColumnTooltip : function(col) {
		return this.config[col].tooltip;
	},

	setColumnTooltip : function(col, tooltip) {
		this.config[col].tooltip = tooltip;
	},


	getDataIndex : function(col) {
		return this.config[col].dataIndex;
	},


	setDataIndex : function(col, dataIndex) {
		this.config[col].dataIndex = dataIndex;
	},


	findColumnIndex : function(dataIndex) {
		var c = this.config;
		for(var i = 0, len = c.length; i < len; i++){
			if(c[i].dataIndex == dataIndex){
				return i;
			}
		}
		return -1;
	},


	isCellEditable : function(colIndex, rowIndex) {
		var c = this.config[colIndex],
		ed = c.editable;


		return !!(ed || (!Ext.isDefined(ed) && c.editor));
	},


	getCellEditor : function(colIndex, rowIndex) {
		return this.config[colIndex].getCellEditor(rowIndex);
	},


	setEditable : function(col, editable) {
		this.config[col].editable = editable;
	},


	isHidden : function(colIndex) {
		return !!this.config[colIndex].hidden;
	},


	isFixed : function(colIndex) {
		return !!this.config[colIndex].fixed;
	},


	isResizable : function(colIndex) {
		return colIndex >= 0 && this.config[colIndex].resizable !== false && this.config[colIndex].fixed !== true;
	},


	setHidden : function(colIndex, hidden) {
		var c = this.config[colIndex];
		if(c.hidden !== hidden){
			c.hidden = hidden;
			this.totalWidth = null;
			this.fireEvent("hiddenchange", this, colIndex, hidden);
		}
	},


	setEditor : function(col, editor) {
		this.config[col].setEditor(editor);
	},


	destroy : function() {
		var length = this.config.length,
		i = 0;

		for (; i < length; i++){
			this.config[i].destroy();
		}
		delete this.config;
		delete this.lookup;
		this.purgeListeners();
	},


	setState : function(col, state) {
		state = Ext.applyIf(state, this.defaults);
		Ext.apply(this.config[col], state);
	}
});


Ext.grid.ColumnModel.defaultRenderer = function(value) {
	if (typeof value == "string" && value.length < 1) {
		return "&#160;";
	}
	return value;
};
Ext.grid.AbstractSelectionModel = Ext.extend(Ext.util.Observable,  {


	constructor : function(){
		this.locked = false;
		Ext.grid.AbstractSelectionModel.superclass.constructor.call(this);
	},


	init : function(grid){
		this.grid = grid;
		if(this.lockOnInit){
			delete this.lockOnInit;
			this.locked = false;
			this.lock();
		}
		this.initEvents();
	},


	lock : function(){
		if(!this.locked){
			this.locked = true;

			var g = this.grid;
			if(g){
				g.getView().on({
					scope: this,
					beforerefresh: this.sortUnLock,
					refresh: this.sortLock
				});
			}else{
				this.lockOnInit = true;
			}
		}
	},


	sortLock : function() {
		this.locked = true;
	},


	sortUnLock : function() {
		this.locked = false;
	},


	unlock : function(){
		if(this.locked){
			this.locked = false;
			var g = this.grid,
			gv;


			if(g){
				gv = g.getView();
				gv.un('beforerefresh', this.sortUnLock, this);
				gv.un('refresh', this.sortLock, this);
			}else{
				delete this.lockOnInit;
			}
		}
	},


	isLocked : function(){
		return this.locked;
	},

	destroy: function(){
		this.unlock();
		this.purgeListeners();
	}
});
Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {

	singleSelect : false,

	constructor : function(config){
		Ext.apply(this, config);
		this.selections = new Ext.util.MixedCollection(false, function(o){
			return o.id;
		});

		this.last = false;
		this.lastActive = false;

		this.addEvents(

			'selectionchange',

			'beforerowselect',

			'rowselect',

			'rowdeselect'
			);
		Ext.grid.RowSelectionModel.superclass.constructor.call(this);
	},



	initEvents : function(){

		if(!this.grid.enableDragDrop && !this.grid.enableDrag){
			this.grid.on('rowmousedown', this.handleMouseDown, this);
		}

		this.rowNav = new Ext.KeyNav(this.grid.getGridEl(), {
			up: this.onKeyPress,
			down: this.onKeyPress,
			scope: this
		});

		this.grid.getView().on({
			scope: this,
			refresh: this.onRefresh,
			rowupdated: this.onRowUpdated,
			rowremoved: this.onRemove
		});
	},

	onKeyPress : function(e, name){
		var up = name == 'up',
		method = up ? 'selectPrevious' : 'selectNext',
		add = up ? -1 : 1,
		last;
		if(!e.shiftKey || this.singleSelect){
			this[method](false);
		}else if(this.last !== false && this.lastActive !== false){
			last = this.last;
			this.selectRange(this.last,  this.lastActive + add);
			this.grid.getView().focusRow(this.lastActive);
			if(last !== false){
				this.last = last;
			}
		}else{
			this.selectFirstRow();
		}
	},


	onRefresh : function(){
		var ds = this.grid.store,
		s = this.getSelections(),
		i = 0,
		len = s.length,
		index, r;

		this.silent = true;
		this.clearSelections(true);
		for(; i < len; i++){
			r = s[i];
			if((index = ds.indexOfId(r.id)) != -1){
				this.selectRow(index, true);
			}
		}
		if(s.length != this.selections.getCount()){
			this.fireEvent('selectionchange', this);
		}
		this.silent = false;
	},


	onRemove : function(v, index, r){
		if(this.selections.remove(r) !== false){
			this.fireEvent('selectionchange', this);
		}
	},


	onRowUpdated : function(v, index, r){
		if(this.isSelected(r)){
			v.onRowSelect(index);
		}
	},


	selectRecords : function(records, keepExisting){
		if(!keepExisting){
			this.clearSelections();
		}
		var ds = this.grid.store,
		i = 0,
		len = records.length;
		for(; i < len; i++){
			this.selectRow(ds.indexOf(records[i]), true);
		}
	},


	getCount : function(){
		return this.selections.length;
	},


	selectFirstRow : function(){
		this.selectRow(0);
	},


	selectLastRow : function(keepExisting){
		this.selectRow(this.grid.store.getCount() - 1, keepExisting);
	},


	selectNext : function(keepExisting){
		if(this.hasNext()){
			this.selectRow(this.last+1, keepExisting);
			this.grid.getView().focusRow(this.last);
			return true;
		}
		return false;
	},


	selectPrevious : function(keepExisting){
		if(this.hasPrevious()){
			this.selectRow(this.last-1, keepExisting);
			this.grid.getView().focusRow(this.last);
			return true;
		}
		return false;
	},


	hasNext : function(){
		return this.last !== false && (this.last+1) < this.grid.store.getCount();
	},


	hasPrevious : function(){
		return !!this.last;
	},



	getSelections : function(){
		return [].concat(this.selections.items);
	},


	getSelected : function(){
		return this.selections.itemAt(0);
	},


	each : function(fn, scope){
		var s = this.getSelections(),
		i = 0,
		len = s.length;

		for(; i < len; i++){
			if(fn.call(scope || this, s[i], i) === false){
				return false;
			}
		}
		return true;
	},


	clearSelections : function(fast){
		if(this.isLocked()){
			return;
		}
		if(fast !== true){
			var ds = this.grid.store,
			s = this.selections;
			s.each(function(r){
				this.deselectRow(ds.indexOfId(r.id));
			}, this);
			s.clear();
		}else{
			this.selections.clear();
		}
		this.last = false;
	},



	selectAll : function(){
		if(this.isLocked()){
			return;
		}
		this.selections.clear();
		for(var i = 0, len = this.grid.store.getCount(); i < len; i++){
			this.selectRow(i, true);
		}
	},


	hasSelection : function(){
		return this.selections.length > 0;
	},


	isSelected : function(index){
		var r = Ext.isNumber(index) ? this.grid.store.getAt(index) : index;
		return (r && this.selections.key(r.id) ? true : false);
	},


	isIdSelected : function(id){
		return (this.selections.key(id) ? true : false);
	},


	handleMouseDown : function(g, rowIndex, e){
		if(e.button !== 0 || this.isLocked()){
			return;
		}
		var view = this.grid.getView();
		if(e.shiftKey && !this.singleSelect && this.last !== false){
			var last = this.last;
			this.selectRange(last, rowIndex, e.ctrlKey);
			this.last = last;
			view.focusRow(rowIndex);
		}else{
			var isSelected = this.isSelected(rowIndex);
			if(e.ctrlKey && isSelected){
				this.deselectRow(rowIndex);
			}else if(!isSelected || this.getCount() > 1){
				this.selectRow(rowIndex, e.ctrlKey || e.shiftKey);
				view.focusRow(rowIndex);
			}
		}
	},


	selectRows : function(rows, keepExisting){
		if(!keepExisting){
			this.clearSelections();
		}
		for(var i = 0, len = rows.length; i < len; i++){
			this.selectRow(rows[i], true);
		}
	},


	selectRange : function(startRow, endRow, keepExisting){
		var i;
		if(this.isLocked()){
			return;
		}
		if(!keepExisting){
			this.clearSelections();
		}
		if(startRow <= endRow){
			for(i = startRow; i <= endRow; i++){
				this.selectRow(i, true);
			}
		}else{
			for(i = startRow; i >= endRow; i--){
				this.selectRow(i, true);
			}
		}
	},


	deselectRange : function(startRow, endRow, preventViewNotify){
		if(this.isLocked()){
			return;
		}
		for(var i = startRow; i <= endRow; i++){
			this.deselectRow(i, preventViewNotify);
		}
	},


	selectRow : function(index, keepExisting, preventViewNotify){
		if(this.isLocked() || (index < 0 || index >= this.grid.store.getCount()) || (keepExisting && this.isSelected(index))){
			return;
		}
		var r = this.grid.store.getAt(index);
		if(r && this.fireEvent('beforerowselect', this, index, keepExisting, r) !== false){
			if(!keepExisting || this.singleSelect){
				this.clearSelections();
			}
			this.selections.add(r);
			this.last = this.lastActive = index;
			if(!preventViewNotify){
				this.grid.getView().onRowSelect(index);
			}
			if(!this.silent){
				this.fireEvent('rowselect', this, index, r);
				this.fireEvent('selectionchange', this);
			}
		}
	},


	deselectRow : function(index, preventViewNotify){
		if(this.isLocked()){
			return;
		}
		if(this.last == index){
			this.last = false;
		}
		if(this.lastActive == index){
			this.lastActive = false;
		}
		var r = this.grid.store.getAt(index);
		if(r){
			this.selections.remove(r);
			if(!preventViewNotify){
				this.grid.getView().onRowDeselect(index);
			}
			this.fireEvent('rowdeselect', this, index, r);
			this.fireEvent('selectionchange', this);
		}
	},


	acceptsNav : function(row, col, cm){
		return !cm.isHidden(col) && cm.isCellEditable(col, row);
	},


	onEditorKey : function(field, e){
		var k = e.getKey(),
		newCell,
		g = this.grid,
		last = g.lastEdit,
		ed = g.activeEditor,
		shift = e.shiftKey,
		ae, last, r, c;

		if(k == e.TAB){
			e.stopEvent();
			ed.completeEdit();
			if(shift){
				newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
			}else{
				newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
			}
		}else if(k == e.ENTER){
			if(this.moveEditorOnEnter !== false){
				if(shift){
					newCell = g.walkCells(last.row - 1, last.col, -1, this.acceptsNav, this);
				}else{
					newCell = g.walkCells(last.row + 1, last.col, 1, this.acceptsNav, this);
				}
			}
		}
		if(newCell){
			r = newCell[0];
			c = newCell[1];

			this.onEditorSelect(r, last.row);

			if(g.isEditor && g.editing){
				ae = g.activeEditor;
				if(ae && ae.field.triggerBlur){

					ae.field.triggerBlur();
				}
			}
			g.startEditing(r, c);
		}
	},

	onEditorSelect: function(row, lastRow){
		if(lastRow != row){
			this.selectRow(row);
		}
	},

	destroy : function(){
		Ext.destroy(this.rowNav);
		this.rowNav = null;
		Ext.grid.RowSelectionModel.superclass.destroy.call(this);
	}
});

Ext.grid.Column = Ext.extend(Ext.util.Observable, {
























	isColumn : true,

	constructor : function(config){
		Ext.apply(this, config);

		if(Ext.isString(this.renderer)){
			this.renderer = Ext.util.Format[this.renderer];
		}else if(Ext.isObject(this.renderer)){
			this.scope = this.renderer.scope;
			this.renderer = this.renderer.fn;
		}
		if(!this.scope){
			this.scope = this;
		}

		var ed = this.editor;
		delete this.editor;
		this.setEditor(ed);
		this.addEvents(

			'click',

			'contextmenu',

			'dblclick',

			'mousedown'
			);
		Ext.grid.Column.superclass.constructor.call(this);
	},


	processEvent : function(name, e, grid, rowIndex, colIndex){
		return this.fireEvent(name, this, grid, rowIndex, e);
	},


	destroy: function() {
		if(this.setEditor){
			this.setEditor(null);
		}
		this.purgeListeners();
	},


	renderer : function(value){
		return value;
	},


	getEditor: function(rowIndex){
		return this.editable !== false ? this.editor : null;
	},


	setEditor : function(editor){
		var ed = this.editor;
		if(ed){
			if(ed.gridEditor){
				ed.gridEditor.destroy();
				delete ed.gridEditor;
			}else{
				ed.destroy();
			}
		}
		this.editor = null;
		if(editor){

			if(!editor.isXType){
				editor = Ext.create(editor, 'textfield');
			}
			this.editor = editor;
		}
	},


	getCellEditor: function(rowIndex){
		var ed = this.getEditor(rowIndex);
		if(ed){
			if(!ed.startEdit){
				if(!ed.gridEditor){
					ed.gridEditor = new Ext.grid.GridEditor(ed);
				}
				ed = ed.gridEditor;
			}
		}
		return ed;
	}
});


Ext.grid.BooleanColumn = Ext.extend(Ext.grid.Column, {

	trueText: 'true',

	falseText: 'false',

	undefinedText: '&#160;',

	constructor: function(cfg){
		Ext.grid.BooleanColumn.superclass.constructor.call(this, cfg);
		var t = this.trueText, f = this.falseText, u = this.undefinedText;
		this.renderer = function(v){
			if(v === undefined){
				return u;
			}
			if(!v || v === 'false'){
				return f;
			}
			return t;
		};
	}
});


Ext.grid.NumberColumn = Ext.extend(Ext.grid.Column, {

	format : '0,000.00',
	constructor: function(cfg){
		Ext.grid.NumberColumn.superclass.constructor.call(this, cfg);
		this.renderer = Ext.util.Format.numberRenderer(this.format);
	}
});


Ext.grid.DateColumn = Ext.extend(Ext.grid.Column, {

	format : 'm/d/Y',
	constructor: function(cfg){
		Ext.grid.DateColumn.superclass.constructor.call(this, cfg);
		this.renderer = Ext.util.Format.dateRenderer(this.format);
	}
});


Ext.grid.TemplateColumn = Ext.extend(Ext.grid.Column, {

	constructor: function(cfg){
		Ext.grid.TemplateColumn.superclass.constructor.call(this, cfg);
		var tpl = (!Ext.isPrimitive(this.tpl) && this.tpl.compile) ? this.tpl : new Ext.XTemplate(this.tpl);
		this.renderer = function(value, p, r){
			return tpl.apply(r.data);
		};
		this.tpl = tpl;
	}
});


Ext.grid.ActionColumn = Ext.extend(Ext.grid.Column, {








	header: '&#160;',

	actionIdRe: /x-action-col-(\d+)/,


	altText: '',

	constructor: function(cfg) {
		var me = this,
		items = cfg.items || (me.items = [me]),
		l = items.length,
		i,
		item;

		Ext.grid.ActionColumn.superclass.constructor.call(me, cfg);



		me.renderer = function(v, meta) {

			v = Ext.isFunction(cfg.renderer) ? cfg.renderer.apply(this, arguments)||'' : '';

			meta.css += ' x-action-col-cell';
			for (i = 0; i < l; i++) {
				item = items[i];
				v += '<img alt="' + me.altText + '" src="' + (item.icon || Ext.BLANK_IMAGE_URL) +
				'" class="x-action-col-icon x-action-col-' + String(i) + ' ' + (item.iconCls || '') +
				' ' + (Ext.isFunction(item.getClass) ? item.getClass.apply(item.scope||this.scope||this, arguments) : '') + '"' +
				((item.tooltip) ? ' ext:qtip="' + item.tooltip + '"' : '') + ' />';
			}
			return v;
		};
	},

	destroy: function() {
		delete this.items;
		delete this.renderer;
		return Ext.grid.ActionColumn.superclass.destroy.apply(this, arguments);
	},


	processEvent : function(name, e, grid, rowIndex, colIndex){
		var m = e.getTarget().className.match(this.actionIdRe),
		item, fn;
		if (m && (item = this.items[parseInt(m[1], 10)])) {
			if (name == 'click') {
				(fn = item.handler || this.handler) && fn.call(item.scope||this.scope||this, grid, rowIndex, colIndex, item, e);
			} else if ((name == 'mousedown') && (item.stopSelection !== false)) {
				return false;
			}
		}
		return Ext.grid.ActionColumn.superclass.processEvent.apply(this, arguments);
	}
});


Ext.grid.Column.types = {
	gridcolumn : Ext.grid.Column,
	booleancolumn: Ext.grid.BooleanColumn,
	numbercolumn: Ext.grid.NumberColumn,
	datecolumn: Ext.grid.DateColumn,
	templatecolumn: Ext.grid.TemplateColumn,
	actioncolumn: Ext.grid.ActionColumn
};
Ext.grid.RowNumberer = Ext.extend(Object, {

	header: "",

	width: 23,

	sortable: false,

	constructor : function(config){
		Ext.apply(this, config);
		if(this.rowspan){
			this.renderer = this.renderer.createDelegate(this);
		}
	},


	fixed:true,
	hideable: false,
	menuDisabled:true,
	dataIndex: '',
	id: 'numberer',
	rowspan: undefined,


	renderer : function(v, p, record, rowIndex){
		if(this.rowspan){
			p.cellAttr = 'rowspan="'+this.rowspan+'"';
		}
		return rowIndex+1;
	}
});
Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {



	header : '<div class="x-grid3-hd-checker">&#160;</div>',

	width : 20,

	sortable : false,


	menuDisabled : true,
	fixed : true,
	hideable: false,
	dataIndex : '',
	id : 'checker',
	isColumn: true,

	constructor : function(){
		Ext.grid.CheckboxSelectionModel.superclass.constructor.apply(this, arguments);
		if(this.checkOnly){
			this.handleMouseDown = Ext.emptyFn;
		}
	},


	initEvents : function(){
		Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);
		this.grid.on('render', function(){
			Ext.fly(this.grid.getView().innerHd).on('mousedown', this.onHdMouseDown, this);
		}, this);
	},


	processEvent : function(name, e, grid, rowIndex, colIndex){
		if (name == 'mousedown') {
			this.onMouseDown(e, e.getTarget());
			return false;
		} else {
			return Ext.grid.Column.prototype.processEvent.apply(this, arguments);
		}
	},


	onMouseDown : function(e, t){
		if(e.button === 0 && t.className == 'x-grid3-row-checker'){
			e.stopEvent();
			var row = e.getTarget('.x-grid3-row');
			if(row){
				var index = row.rowIndex;
				if(this.isSelected(index)){
					this.deselectRow(index);
				}else{
					this.selectRow(index, true);
					this.grid.getView().focusRow(index);
				}
			}
		}
	},


	onHdMouseDown : function(e, t) {
		if(t.className == 'x-grid3-hd-checker'){
			e.stopEvent();
			var hd = Ext.fly(t.parentNode);
			var isChecked = hd.hasClass('x-grid3-hd-checker-on');
			if(isChecked){
				hd.removeClass('x-grid3-hd-checker-on');
				this.clearSelections();
			}else{
				hd.addClass('x-grid3-hd-checker-on');
				this.selectAll();
			}
		}
	},


	renderer : function(v, p, record){
		return '<div class="x-grid3-row-checker">&#160;</div>';
	},

	onEditorSelect: function(row, lastRow){
		if(lastRow != row && !this.checkOnly){
			this.selectRow(row);
		}
	}
});
Ext.grid.CellSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {

	constructor : function(config){
		Ext.apply(this, config);

		this.selection = null;

		this.addEvents(

			"beforecellselect",

			"cellselect",

			"selectionchange"
			);

		Ext.grid.CellSelectionModel.superclass.constructor.call(this);
	},


	initEvents : function(){
		this.grid.on('cellmousedown', this.handleMouseDown, this);
		this.grid.on(Ext.EventManager.getKeyEvent(), this.handleKeyDown, this);
		this.grid.getView().on({
			scope: this,
			refresh: this.onViewChange,
			rowupdated: this.onRowUpdated,
			beforerowremoved: this.clearSelections,
			beforerowsinserted: this.clearSelections
		});
		if(this.grid.isEditor){
			this.grid.on('beforeedit', this.beforeEdit,  this);
		}
	},


	beforeEdit : function(e){
		this.select(e.row, e.column, false, true, e.record);
	},


	onRowUpdated : function(v, index, r){
		if(this.selection && this.selection.record == r){
			v.onCellSelect(index, this.selection.cell[1]);
		}
	},


	onViewChange : function(){
		this.clearSelections(true);
	},


	getSelectedCell : function(){
		return this.selection ? this.selection.cell : null;
	},


	clearSelections : function(preventNotify){
		var s = this.selection;
		if(s){
			if(preventNotify !== true){
				this.grid.view.onCellDeselect(s.cell[0], s.cell[1]);
			}
			this.selection = null;
			this.fireEvent("selectionchange", this, null);
		}
	},


	hasSelection : function(){
		return this.selection ? true : false;
	},


	handleMouseDown : function(g, row, cell, e){
		if(e.button !== 0 || this.isLocked()){
			return;
		}
		this.select(row, cell);
	},


	select : function(rowIndex, colIndex, preventViewNotify, preventFocus,  r){
		if(this.fireEvent("beforecellselect", this, rowIndex, colIndex) !== false){
			this.clearSelections();
			r = r || this.grid.store.getAt(rowIndex);
			this.selection = {
				record : r,
				cell : [rowIndex, colIndex]
			};
			if(!preventViewNotify){
				var v = this.grid.getView();
				v.onCellSelect(rowIndex, colIndex);
				if(preventFocus !== true){
					v.focusCell(rowIndex, colIndex);
				}
			}
			this.fireEvent("cellselect", this, rowIndex, colIndex);
			this.fireEvent("selectionchange", this, this.selection);
		}
	},


	isSelectable : function(rowIndex, colIndex, cm){
		return !cm.isHidden(colIndex);
	},


	onEditorKey: function(field, e){
		if(e.getKey() == e.TAB){
			this.handleKeyDown(e);
		}
	},


	handleKeyDown : function(e){
		if(!e.isNavKeyPress()){
			return;
		}

		var k = e.getKey(),
		g = this.grid,
		s = this.selection,
		sm = this,
		walk = function(row, col, step){
			return g.walkCells(
				row,
				col,
				step,
				g.isEditor && g.editing ? sm.acceptsNav : sm.isSelectable,
				sm
				);
		},
		cell, newCell, r, c, ae;

		switch(k){
			case e.ESC:
			case e.PAGE_UP:
			case e.PAGE_DOWN:

				break;
			default:

				e.stopEvent();
				break;
		}

		if(!s){
			cell = walk(0, 0, 1);
			if(cell){
				this.select(cell[0], cell[1]);
			}
			return;
		}

		cell = s.cell;
		r = cell[0];
		c = cell[1];

		switch(k){
			case e.TAB:
				if(e.shiftKey){
					newCell = walk(r, c - 1, -1);
				}else{
					newCell = walk(r, c + 1, 1);
				}
				break;
			case e.DOWN:
				newCell = walk(r + 1, c, 1);
				break;
			case e.UP:
				newCell = walk(r - 1, c, -1);
				break;
			case e.RIGHT:
				newCell = walk(r, c + 1, 1);
				break;
			case e.LEFT:
				newCell = walk(r, c - 1, -1);
				break;
			case e.ENTER:
				if (g.isEditor && !g.editing) {
					g.startEditing(r, c);
					return;
				}
				break;
		}

		if(newCell){

			r = newCell[0];
			c = newCell[1];

			this.select(r, c);

			if(g.isEditor && g.editing){
				ae = g.activeEditor;
				if(ae && ae.field.triggerBlur){

					ae.field.triggerBlur();
				}
				g.startEditing(r, c);
			}
		}
	},

	acceptsNav : function(row, col, cm){
		return !cm.isHidden(col) && cm.isCellEditable(col, row);
	}
});
Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {

	clicksToEdit: 2,


	forceValidation: false,


	isEditor : true,

	detectEdit: false,


	autoEncode : false,



	trackMouseOver: false,


	initComponent : function(){
		Ext.grid.EditorGridPanel.superclass.initComponent.call(this);

		if(!this.selModel){

			this.selModel = new Ext.grid.CellSelectionModel();
		}

		this.activeEditor = null;

		this.addEvents(

			"beforeedit",

			"afteredit",

			"validateedit"
			);
	},


	initEvents : function(){
		Ext.grid.EditorGridPanel.superclass.initEvents.call(this);

		this.getGridEl().on('mousewheel', this.stopEditing.createDelegate(this, [true]), this);
		this.on('columnresize', this.stopEditing, this, [true]);

		if(this.clicksToEdit == 1){
			this.on("cellclick", this.onCellDblClick, this);
		}else {
			var view = this.getView();
			if(this.clicksToEdit == 'auto' && view.mainBody){
				view.mainBody.on('mousedown', this.onAutoEditClick, this);
			}
			this.on('celldblclick', this.onCellDblClick, this);
		}
	},

	onResize : function(){
		Ext.grid.EditorGridPanel.superclass.onResize.apply(this, arguments);
		var ae = this.activeEditor;
		if(this.editing && ae){
			ae.realign(true);
		}
	},


	onCellDblClick : function(g, row, col){
		this.startEditing(row, col);
	},


	onAutoEditClick : function(e, t){
		if(e.button !== 0){
			return;
		}
		var row = this.view.findRowIndex(t),
		col = this.view.findCellIndex(t);
		if(row !== false && col !== false){
			this.stopEditing();
			if(this.selModel.getSelectedCell){
				var sc = this.selModel.getSelectedCell();
				if(sc && sc[0] === row && sc[1] === col){
					this.startEditing(row, col);
				}
			}else{
				if(this.selModel.isSelected(row)){
					this.startEditing(row, col);
				}
			}
		}
	},


	onEditComplete : function(ed, value, startValue){
		this.editing = false;
		this.lastActiveEditor = this.activeEditor;
		this.activeEditor = null;

		var r = ed.record,
		field = this.colModel.getDataIndex(ed.col);
		value = this.postEditValue(value, startValue, r, field);
		if(this.forceValidation === true || String(value) !== String(startValue)){
			var e = {
				grid: this,
				record: r,
				field: field,
				originalValue: startValue,
				value: value,
				row: ed.row,
				column: ed.col,
				cancel:false
			};
			if(this.fireEvent("validateedit", e) !== false && !e.cancel && String(value) !== String(startValue)){
				r.set(field, e.value);
				delete e.cancel;
				this.fireEvent("afteredit", e);
			}
		}
		this.view.focusCell(ed.row, ed.col);
	},


	startEditing : function(row, col){
		this.stopEditing();
		if(this.colModel.isCellEditable(col, row)){
			this.view.ensureVisible(row, col, true);
			var r = this.store.getAt(row),
			field = this.colModel.getDataIndex(col),
			e = {
				grid: this,
				record: r,
				field: field,
				value: r.data[field],
				row: row,
				column: col,
				cancel:false
			};
			if(this.fireEvent("beforeedit", e) !== false && !e.cancel){
				this.editing = true;
				var ed = this.colModel.getCellEditor(col, row);
				if(!ed){
					return;
				}
				if(!ed.rendered){
					ed.parentEl = this.view.getEditorParent(ed);
					ed.on({
						scope: this,
						render: {
							fn: function(c){
								c.field.focus(false, true);
							},
							single: true,
							scope: this
						},
						specialkey: function(field, e){
							this.getSelectionModel().onEditorKey(field, e);
						},
						complete: this.onEditComplete,
						canceledit: this.stopEditing.createDelegate(this, [true])
					});
				}
				Ext.apply(ed, {
					row     : row,
					col     : col,
					record  : r
				});
				this.lastEdit = {
					row: row,
					col: col
				};
				this.activeEditor = ed;


				ed.selectSameEditor = (this.activeEditor == this.lastActiveEditor);
				var v = this.preEditValue(r, field);
				ed.startEdit(this.view.getCell(row, col).firstChild, Ext.isDefined(v) ? v : '');


				(function(){
					delete ed.selectSameEditor;
				}).defer(50);
			}
		}
	},


	preEditValue : function(r, field){
		var value = r.data[field];
		return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlDecode(value) : value;
	},


	postEditValue : function(value, originalValue, r, field){
		return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlEncode(value) : value;
	},


	stopEditing : function(cancel){
		if(this.editing){

			var ae = this.lastActiveEditor = this.activeEditor;
			if(ae){
				ae[cancel === true ? 'cancelEdit' : 'completeEdit']();
				this.view.focusCell(ae.row, ae.col);
			}
			this.activeEditor = null;
		}
		this.editing = false;
	}
});
Ext.reg('editorgrid', Ext.grid.EditorGridPanel);

Ext.grid.GridEditor = function(field, config){
	Ext.grid.GridEditor.superclass.constructor.call(this, field, config);
	field.monitorTab = false;
};

Ext.extend(Ext.grid.GridEditor, Ext.Editor, {
	alignment: "tl-tl",
	autoSize: "width",
	hideEl : false,
	cls: "x-small-editor x-grid-editor",
	shim:false,
	shadow:false
});
Ext.grid.PropertyRecord = Ext.data.Record.create([
{
	name:'name',
	type:'string'
}, 'value'
]);


Ext.grid.PropertyStore = Ext.extend(Ext.util.Observable, {

	constructor : function(grid, source){
		this.grid = grid;
		this.store = new Ext.data.Store({
			recordType : Ext.grid.PropertyRecord
		});
		this.store.on('update', this.onUpdate,  this);
		if(source){
			this.setSource(source);
		}
		Ext.grid.PropertyStore.superclass.constructor.call(this);
	},


	setSource : function(o){
		this.source = o;
		this.store.removeAll();
		var data = [];
		for(var k in o){
			if(this.isEditableValue(o[k])){
				data.push(new Ext.grid.PropertyRecord({
					name: k,
					value: o[k]
					}, k));
			}
		}
		this.store.loadRecords({
			records: data
		}, {}, true);
	},


	onUpdate : function(ds, record, type){
		if(type == Ext.data.Record.EDIT){
			var v = record.data.value;
			var oldValue = record.modified.value;
			if(this.grid.fireEvent('beforepropertychange', this.source, record.id, v, oldValue) !== false){
				this.source[record.id] = v;
				record.commit();
				this.grid.fireEvent('propertychange', this.source, record.id, v, oldValue);
			}else{
				record.reject();
			}
		}
	},


	getProperty : function(row){
		return this.store.getAt(row);
	},


	isEditableValue: function(val){
		return Ext.isPrimitive(val) || Ext.isDate(val);
	},


	setValue : function(prop, value, create){
		var r = this.getRec(prop);
		if(r){
			r.set('value', value);
			this.source[prop] = value;
		}else if(create){

			this.source[prop] = value;
			r = new Ext.grid.PropertyRecord({
				name: prop,
				value: value
			}, prop);
			this.store.add(r);

		}
	},


	remove : function(prop){
		var r = this.getRec(prop);
		if(r){
			this.store.remove(r);
			delete this.source[prop];
		}
	},


	getRec : function(prop){
		return this.store.getById(prop);
	},


	getSource : function(){
		return this.source;
	}
});


Ext.grid.PropertyColumnModel = Ext.extend(Ext.grid.ColumnModel, {

	nameText : 'Name',
	valueText : 'Value',
	dateFormat : 'm/j/Y',
	trueText: 'true',
	falseText: 'false',

	constructor : function(grid, store){
		var g = Ext.grid,
		f = Ext.form;

		this.grid = grid;
		g.PropertyColumnModel.superclass.constructor.call(this, [
		{
			header: this.nameText,
			width:50,
			sortable: true,
			dataIndex:'name',
			id: 'name',
			menuDisabled:true
		},

		{
			header: this.valueText,
			width:50,
			resizable:false,
			dataIndex: 'value',
			id: 'value',
			menuDisabled:true
		}
		]);
		this.store = store;

		var bfield = new f.Field({
			autoCreate: {
				tag: 'select',
				children: [

				{
					tag: 'option',
					value: 'true',
					html: this.trueText
					},

					{
					tag: 'option',
					value: 'false',
					html: this.falseText
					}
				]
				},
			getValue : function(){
				return this.el.dom.value == 'true';
			}
		});
		this.editors = {
			'date' : new g.GridEditor(new f.DateField({
				selectOnFocus:true
			})),
			'string' : new g.GridEditor(new f.TextField({
				selectOnFocus:true
			})),
			'number' : new g.GridEditor(new f.NumberField({
				selectOnFocus:true,
				style:'text-align:left;'
			})),
			'boolean' : new g.GridEditor(bfield, {
				autoSize: 'both'
			})
		};
		this.renderCellDelegate = this.renderCell.createDelegate(this);
		this.renderPropDelegate = this.renderProp.createDelegate(this);
	},


	renderDate : function(dateVal){
		return dateVal.dateFormat(this.dateFormat);
	},


	renderBool : function(bVal){
		return this[bVal ? 'trueText' : 'falseText'];
	},


	isCellEditable : function(colIndex, rowIndex){
		return colIndex == 1;
	},


	getRenderer : function(col){
		return col == 1 ?
		this.renderCellDelegate : this.renderPropDelegate;
	},


	renderProp : function(v){
		return this.getPropertyName(v);
	},


	renderCell : function(val, meta, rec){
		var renderer = this.grid.customRenderers[rec.get('name')];
		if(renderer){
			return renderer.apply(this, arguments);
		}
		var rv = val;
		if(Ext.isDate(val)){
			rv = this.renderDate(val);
		}else if(typeof val == 'boolean'){
			rv = this.renderBool(val);
		}
		return Ext.util.Format.htmlEncode(rv);
	},


	getPropertyName : function(name){
		var pn = this.grid.propertyNames;
		return pn && pn[name] ? pn[name] : name;
	},


	getCellEditor : function(colIndex, rowIndex){
		var p = this.store.getProperty(rowIndex),
		n = p.data.name,
		val = p.data.value;
		if(this.grid.customEditors[n]){
			return this.grid.customEditors[n];
		}
		if(Ext.isDate(val)){
			return this.editors.date;
		}else if(typeof val == 'number'){
			return this.editors.number;
		}else if(typeof val == 'boolean'){
			return this.editors['boolean'];
		}else{
			return this.editors.string;
		}
	},


	destroy : function(){
		Ext.grid.PropertyColumnModel.superclass.destroy.call(this);
		this.destroyEditors(this.editors);
		this.destroyEditors(this.grid.customEditors);
	},

	destroyEditors: function(editors){
		for(var ed in editors){
			Ext.destroy(editors[ed]);
		}
	}
});


Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {







	enableColumnMove:false,
	stripeRows:false,
	trackMouseOver: false,
	clicksToEdit:1,
	enableHdMenu : false,
	viewConfig : {
		forceFit:true
	},


	initComponent : function(){
		this.customRenderers = this.customRenderers || {};
		this.customEditors = this.customEditors || {};
		this.lastEditRow = null;
		var store = new Ext.grid.PropertyStore(this);
		this.propStore = store;
		var cm = new Ext.grid.PropertyColumnModel(this, store);
		store.store.sort('name', 'ASC');
		this.addEvents(

			'beforepropertychange',

			'propertychange'
			);
		this.cm = cm;
		this.ds = store.store;
		Ext.grid.PropertyGrid.superclass.initComponent.call(this);

		this.mon(this.selModel, 'beforecellselect', function(sm, rowIndex, colIndex){
			if(colIndex === 0){
				this.startEditing.defer(200, this, [rowIndex, 1]);
				return false;
			}
		}, this);
	},


	onRender : function(){
		Ext.grid.PropertyGrid.superclass.onRender.apply(this, arguments);

		this.getGridEl().addClass('x-props-grid');
	},


	afterRender: function(){
		Ext.grid.PropertyGrid.superclass.afterRender.apply(this, arguments);
		if(this.source){
			this.setSource(this.source);
		}
	},


	setSource : function(source){
		this.propStore.setSource(source);
	},


	getSource : function(){
		return this.propStore.getSource();
	},


	setProperty : function(prop, value, create){
		this.propStore.setValue(prop, value, create);
	},


	removeProperty : function(prop){
		this.propStore.remove(prop);
	}





});
Ext.reg("propertygrid", Ext.grid.PropertyGrid);

Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {


	groupByText : 'Group By This Field',

	showGroupsText : 'Show in Groups',

	hideGroupedColumn : false,

	showGroupName : true,

	startCollapsed : false,

	enableGrouping : true,

	enableGroupingMenu : true,

	enableNoGroups : true,

	emptyGroupText : '(None)',

	ignoreAdd : false,

	groupTextTpl : '{text}',


	groupMode: 'value',




	cancelEditOnToggle: true,


	initTemplates : function(){
		Ext.grid.GroupingView.superclass.initTemplates.call(this);
		this.state = {};

		var sm = this.grid.getSelectionModel();
		sm.on(sm.selectRow ? 'beforerowselect' : 'beforecellselect',
			this.onBeforeRowSelect, this);

		if(!this.startGroup){
			this.startGroup = new Ext.XTemplate(
				'<div id="{groupId}" class="x-grid-group {cls}">',
				'<div id="{groupId}-hd" class="x-grid-group-hd" style="{style}"><div class="x-grid-group-title">', this.groupTextTpl ,'</div></div>',
				'<div id="{groupId}-bd" class="x-grid-group-body">'
				);
		}
		this.startGroup.compile();

		if (!this.endGroup) {
			this.endGroup = '</div></div>';
		}
	},


	findGroup : function(el){
		return Ext.fly(el).up('.x-grid-group', this.mainBody.dom);
	},


	getGroups : function(){
		return this.hasRows() ? this.mainBody.dom.childNodes : [];
	},


	onAdd : function(ds, records, index) {
		if (this.canGroup() && !this.ignoreAdd) {
			var ss = this.getScrollState();
			this.fireEvent('beforerowsinserted', ds, index, index + (records.length-1));
			this.refresh();
			this.restoreScroll(ss);
			this.fireEvent('rowsinserted', ds, index, index + (records.length-1));
		} else if (!this.canGroup()) {
			Ext.grid.GroupingView.superclass.onAdd.apply(this, arguments);
		}
	},


	onRemove : function(ds, record, index, isUpdate){
		Ext.grid.GroupingView.superclass.onRemove.apply(this, arguments);
		var g = document.getElementById(record._groupId);
		if(g && g.childNodes[1].childNodes.length < 1){
			Ext.removeNode(g);
		}
		this.applyEmptyText();
	},


	refreshRow : function(record){
		if(this.ds.getCount()==1){
			this.refresh();
		}else{
			this.isUpdating = true;
			Ext.grid.GroupingView.superclass.refreshRow.apply(this, arguments);
			this.isUpdating = false;
		}
	},


	beforeMenuShow : function(){
		var item, items = this.hmenu.items, disabled = this.cm.config[this.hdCtxIndex].groupable === false;
		if((item = items.get('groupBy'))){
			item.setDisabled(disabled);
		}
		if((item = items.get('showGroups'))){
			item.setDisabled(disabled);
			item.setChecked(this.canGroup(), true);
		}
	},


	renderUI : function(){
		var markup = Ext.grid.GroupingView.superclass.renderUI.call(this);

		if(this.enableGroupingMenu && this.hmenu){
			this.hmenu.add('-',{
				itemId:'groupBy',
				text: this.groupByText,
				handler: this.onGroupByClick,
				scope: this,
				iconCls:'x-group-by-icon'
			});
			if(this.enableNoGroups){
				this.hmenu.add({
					itemId:'showGroups',
					text: this.showGroupsText,
					checked: true,
					checkHandler: this.onShowGroupsClick,
					scope: this
				});
			}
			this.hmenu.on('beforeshow', this.beforeMenuShow, this);
		}
		return markup;
	},

	processEvent: function(name, e){
		Ext.grid.GroupingView.superclass.processEvent.call(this, name, e);
		var hd = e.getTarget('.x-grid-group-hd', this.mainBody);
		if(hd){

			var field = this.getGroupField(),
			prefix = this.getPrefix(field),
			groupValue = hd.id.substring(prefix.length),
			emptyRe = new RegExp('gp-' + Ext.escapeRe(field) + '--hd');


			groupValue = groupValue.substr(0, groupValue.length - 3);


			if(groupValue || emptyRe.test(hd.id)){
				this.grid.fireEvent('group' + name, this.grid, field, groupValue, e);
			}
			if(name == 'mousedown' && e.button == 0){
				this.toggleGroup(hd.parentNode);
			}
		}

	},


	onGroupByClick : function(){
		var grid = this.grid;
		this.enableGrouping = true;
		grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));
		grid.fireEvent('groupchange', grid, grid.store.getGroupState());
		this.beforeMenuShow();
		this.refresh();
	},


	onShowGroupsClick : function(mi, checked){
		this.enableGrouping = checked;
		if(checked){
			this.onGroupByClick();
		}else{
			this.grid.store.clearGrouping();
			this.grid.fireEvent('groupchange', this, null);
		}
	},


	toggleRowIndex : function(rowIndex, expanded){
		if(!this.canGroup()){
			return;
		}
		var row = this.getRow(rowIndex);
		if(row){
			this.toggleGroup(this.findGroup(row), expanded);
		}
	},


	toggleGroup : function(group, expanded){
		var gel = Ext.get(group);
		expanded = Ext.isDefined(expanded) ? expanded : gel.hasClass('x-grid-group-collapsed');
		if(this.state[gel.id] !== expanded){
			if (this.cancelEditOnToggle !== false) {
				this.grid.stopEditing(true);
			}
			this.state[gel.id] = expanded;
			gel[expanded ? 'removeClass' : 'addClass']('x-grid-group-collapsed');
		}
	},


	toggleAllGroups : function(expanded){
		var groups = this.getGroups();
		for(var i = 0, len = groups.length; i < len; i++){
			this.toggleGroup(groups[i], expanded);
		}
	},


	expandAllGroups : function(){
		this.toggleAllGroups(true);
	},


	collapseAllGroups : function(){
		this.toggleAllGroups(false);
	},


	getGroup : function(v, r, groupRenderer, rowIndex, colIndex, ds){
		var column = this.cm.config[colIndex],
		g = groupRenderer ? groupRenderer.call(column.scope, v, {}, r, rowIndex, colIndex, ds) : String(v);
		if(g === '' || g === '&#160;'){
			g = column.emptyGroupText || this.emptyGroupText;
		}
		return g;
	},


	getGroupField : function(){
		return this.grid.store.getGroupState();
	},


	afterRender : function(){
		if(!this.ds || !this.cm){
			return;
		}
		Ext.grid.GroupingView.superclass.afterRender.call(this);
		if(this.grid.deferRowRender){
			this.updateGroupWidths();
		}
	},

	afterRenderUI: function () {
		Ext.grid.GroupingView.superclass.afterRenderUI.call(this);

		if (this.enableGroupingMenu && this.hmenu) {
			this.hmenu.add('-',{
				itemId:'groupBy',
				text: this.groupByText,
				handler: this.onGroupByClick,
				scope: this,
				iconCls:'x-group-by-icon'
			});

			if (this.enableNoGroups) {
				this.hmenu.add({
					itemId:'showGroups',
					text: this.showGroupsText,
					checked: true,
					checkHandler: this.onShowGroupsClick,
					scope: this
				});
			}

			this.hmenu.on('beforeshow', this.beforeMenuShow, this);
		}
	},


	renderRows : function(){
		var groupField = this.getGroupField();
		var eg = !!groupField;

		if(this.hideGroupedColumn) {
			var colIndex = this.cm.findColumnIndex(groupField),
			hasLastGroupField = Ext.isDefined(this.lastGroupField);
			if(!eg && hasLastGroupField){
				this.mainBody.update('');
				this.cm.setHidden(this.cm.findColumnIndex(this.lastGroupField), false);
				delete this.lastGroupField;
			}else if (eg && !hasLastGroupField){
				this.lastGroupField = groupField;
				this.cm.setHidden(colIndex, true);
			}else if (eg && hasLastGroupField && groupField !== this.lastGroupField) {
				this.mainBody.update('');
				var oldIndex = this.cm.findColumnIndex(this.lastGroupField);
				this.cm.setHidden(oldIndex, false);
				this.lastGroupField = groupField;
				this.cm.setHidden(colIndex, true);
			}
		}
		return Ext.grid.GroupingView.superclass.renderRows.apply(
			this, arguments);
	},


	doRender : function(cs, rs, ds, startRow, colCount, stripe){
		if(rs.length < 1){
			return '';
		}

		if(!this.canGroup() || this.isUpdating){
			return Ext.grid.GroupingView.superclass.doRender.apply(this, arguments);
		}

		var groupField = this.getGroupField(),
		colIndex = this.cm.findColumnIndex(groupField),
		g,
		gstyle = 'width:' + this.getTotalWidth() + ';',
		cfg = this.cm.config[colIndex],
		groupRenderer = cfg.groupRenderer || cfg.renderer,
		prefix = this.showGroupName ? (cfg.groupName || cfg.header)+': ' : '',
		groups = [],
		curGroup, i, len, gid;

		for(i = 0, len = rs.length; i < len; i++){
			var rowIndex = startRow + i,
			r = rs[i],
			gvalue = r.data[groupField];

			g = this.getGroup(gvalue, r, groupRenderer, rowIndex, colIndex, ds);
			if(!curGroup || curGroup.group != g){
				gid = this.constructId(gvalue, groupField, colIndex);


				this.state[gid] = !(Ext.isDefined(this.state[gid]) ? !this.state[gid] : this.startCollapsed);
				curGroup = {
					group: g,
					gvalue: gvalue,
					text: prefix + g,
					groupId: gid,
					startRow: rowIndex,
					rs: [r],
					cls: this.state[gid] ? '' : 'x-grid-group-collapsed',
					style: gstyle
				};
				groups.push(curGroup);
			}else{
				curGroup.rs.push(r);
			}
			r._groupId = gid;
		}

		var buf = [];
		for(i = 0, len = groups.length; i < len; i++){
			g = groups[i];
			this.doGroupStart(buf, g, cs, ds, colCount);
			buf[buf.length] = Ext.grid.GroupingView.superclass.doRender.call(
				this, cs, g.rs, ds, g.startRow, colCount, stripe);

			this.doGroupEnd(buf, g, cs, ds, colCount);
		}
		return buf.join('');
	},


	getGroupId : function(value){
		var field = this.getGroupField();
		return this.constructId(value, field, this.cm.findColumnIndex(field));
	},


	constructId : function(value, field, idx){
		var cfg = this.cm.config[idx],
		groupRenderer = cfg.groupRenderer || cfg.renderer,
		val = (this.groupMode == 'value') ? value : this.getGroup(value, {
			data:{}
		}, groupRenderer, 0, idx, this.ds);

	return this.getPrefix(field) + Ext.util.Format.htmlEncode(val);
},


canGroup  : function(){
	return this.enableGrouping && !!this.getGroupField();
},


getPrefix: function(field){
	return this.grid.getGridEl().id + '-gp-' + field + '-';
},


doGroupStart : function(buf, g, cs, ds, colCount){
	buf[buf.length] = this.startGroup.apply(g);
},


doGroupEnd : function(buf, g, cs, ds, colCount){
	buf[buf.length] = this.endGroup;
},


getRows : function(){
	if(!this.canGroup()){
		return Ext.grid.GroupingView.superclass.getRows.call(this);
	}
	var r = [],
	gs = this.getGroups(),
	g,
	i = 0,
	len = gs.length,
	j,
	jlen;
	for(; i < len; ++i){
		g = gs[i].childNodes[1];
		if(g){
			g = g.childNodes;
			for(j = 0, jlen = g.length; j < jlen; ++j){
				r[r.length] = g[j];
			}
		}
	}
	return r;
},


updateGroupWidths : function(){
	if(!this.canGroup() || !this.hasRows()){
		return;
	}
	var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth-this.getScrollOffset()) +'px';
	var gs = this.getGroups();
	for(var i = 0, len = gs.length; i < len; i++){
		gs[i].firstChild.style.width = tw;
	}
},


onColumnWidthUpdated : function(col, w, tw){
	Ext.grid.GroupingView.superclass.onColumnWidthUpdated.call(this, col, w, tw);
	this.updateGroupWidths();
},


onAllColumnWidthsUpdated : function(ws, tw){
	Ext.grid.GroupingView.superclass.onAllColumnWidthsUpdated.call(this, ws, tw);
	this.updateGroupWidths();
},


onColumnHiddenUpdated : function(col, hidden, tw){
	Ext.grid.GroupingView.superclass.onColumnHiddenUpdated.call(this, col, hidden, tw);
	this.updateGroupWidths();
},


onLayout : function(){
	this.updateGroupWidths();
},


onBeforeRowSelect : function(sm, rowIndex){
	this.toggleRowIndex(rowIndex, true);
}
});

Ext.grid.GroupingView.GROUP_ID = 1000;
